W poniższym kodzie tworzę podstawową klasę abstrakcyjną Base
. Chcę, aby wszystkie klasy, które dziedziczą, Base
zapewniały name
właściwość, więc utworzyłem tę właściwość jako @abstractmethod
.
Potem stworzył podklasę Base
o nazwie Base_1
, które mają za zadanie dostarczyć pewną funkcjonalność, ale nadal pozostają abstrakcyjne. W programie nie ma name
własności Base_1
, ale mimo to Python instatinuje obiekt tej klasy bez błędu. Jak tworzyć abstrakcyjne właściwości?
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 __name__ == '__main__':
b1 = Base_1('abc')
python
properties
abstract-class
decorator
Boris Gorelik
źródło
źródło
@property
wclass C
,name
powróci do metody.Odpowiedzi:
Od Pythona 3.3 naprawiono błąd, co oznacza, że
property()
dekorator jest teraz poprawnie identyfikowany jako abstrakcyjny po zastosowaniu do metody abstrakcyjnej.Uwaga: zamówienie ma znaczenie, musisz użyć
@property
wcześniej@abstractmethod
Python 3.3+: ( dokumentacja pythona ):
Python 2: ( dokumentacja pythona )
źródło
Do wersji Python 3.3 nie można zagnieżdżać
@abstractmethod
i@property
.Służy
@abstractproperty
do tworzenia właściwości abstrakcyjnych ( dokumentów ).Kod zgłasza teraz poprawny wyjątek:
źródło
@abstractproperty
jest przestarzała na rzecz kombinacji takich jak OP.raise NotImplementedError
Na podstawie powyższej odpowiedzi Jamesa
i użyj go jako dekoratora
źródło