it-swarm.com.de

So erstellen Sie abstrakte Eigenschaften in python abstract classes

Im folgenden Code erstelle ich eine abstrakte Basisklasse Base. Ich möchte, dass alle Klassen, die von Base erben, die Eigenschaft name bereitstellen. Daher habe ich diese Eigenschaft zu einem @abstractmethod Gemacht.

Dann habe ich eine Unterklasse von Base mit dem Namen Base_1 Erstellt, die einige Funktionen bereitstellen soll, aber dennoch abstrakt bleibt. Es gibt keine name -Eigenschaft in Base_1, Aber dennoch python instatiniert ein Objekt dieser Klasse ohne einen Fehler. Wie erstellt man abstrakte Eigenschaften?

from abc import ABCMeta, abstractmethod
class Base(object):
    __metaclass__ = ABCMeta
    def __init__(self, strDirConfig):
        self.strDirConfig = strDirConfig

    @abstractmethod
    def _doStuff(self, signals):
        pass

    @property    
    @abstractmethod
    def name(self):
        #this property will be supplied by the inheriting classes
        #individually
        pass


class Base_1(Base):
    __metaclass__ = ABCMeta
    # this class does not provide the name property, should raise an error
    def __init__(self, strDirConfig):
        super(Base_1, self).__init__(strDirConfig)

    def _doStuff(self, signals):
        print 'Base_1 does stuff'


class C(Base_1):
    @property
    def name(self):
        return 'class C'


if __== '__main__':
    b1 = Base_1('abc')  
71
Boris Gorelik

Da Python 3. ein Fehler behoben wurde, wird der property() -Dekorator jetzt korrekt als abstrakt identifiziert, wenn er auf eine abstrakte Methode angewendet wird.

Hinweis: Bestellangelegenheiten müssen Sie mit @property Vor @abstractmethod

Python 3.3 +: ( Python-Dokumente ):

class C(ABC):
    @property
    @abstractmethod
    def my_abstract_property(self):
        ...

Python 2: ( Python-Dokumente )

class C(ABC):
    @abstractproperty
    def my_abstract_property(self):
        ...
52
James

Bis Python 3. können Sie @abstractmethod Und @property Nicht verschachteln.

Verwenden Sie @abstractproperty, Um abstrakte Eigenschaften zu erstellen ( docs ).

from abc import ABCMeta, abstractmethod, abstractproperty

class Base(object):
    # ...
    @abstractproperty
    def name(self):
        pass

Der Code löst jetzt die richtige Ausnahme aus:

 Traceback (letzter Aufruf zuletzt): 
 Datei "foo.py", Zeile 36, in 
 B1 = Base_1 ('abc') 
 TypeError: Can instanziiert die abstrakte Klasse Base_1 nicht mit dem abstrakten Methodennamen 
41
codeape

Basierend auf der obigen Antwort von James

def compatibleabstractproperty(func):

    if sys.version_info > (3, 3):             
        return property(abstractmethod(func))
    else:
        return abstractproperty(func)

und benutze es als Dekorateur

@compatibleabstractproperty
def env(self):
    raise NotImplementedError()
0
himanshu219