The concept is true; the code ABCMetadoes not distinguish between a abstractpropertyand a abstractmethod.
, .__isabstractmethod__, ABCMeta .__abstractmethods__ (a frozenset) ABC. object , , .__abstractmethods__, . .
:
>>> from abc import *
>>> class C:
... __metaclass__ = ABCMeta
... @abstractmethod
... def abstract_method(self): pass
... @abstractproperty
... def abstract_property(self): return 'foo'
...
>>> C.__abstractmethods__
frozenset(['abstract_method', 'abstract_property'])
, ABCMeta . __isabstractmethod__, __abstractmethods__; , .
ABCMeta.__new__ :
cls = super(ABCMeta, mcls).__new__(mcls, name, bases, namespace)
abstracts = set(name
for name, value in namespace.items()
if getattr(value, "__isabstractmethod__", False))
for base in bases:
for name in getattr(base, "__abstractmethods__", set()):
value = getattr(cls, name, None)
if getattr(value, "__isabstractmethod__", False):
abstracts.add(name)
cls.__abstractmethods__ = frozenset(abstracts)
ABCMeta, __new__ , , , cls .