Actual difference in implementation / overriding with @abstractproperty and @abstractmethod

Consider an abstract base class with the function that you want each subsequent subclass to be redefined. Using the abc and ABCMeta modules; decorating with @abstractpropertyor @abstractmethoddoes it really force the subclass / developer to implement the type of function defined by the decorator? From my experiments, you can override an abstract property using a method and an abstract method with a property in a subclass.

Is this concept wrong?

+5
source share
1 answer

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)
# Compute set of abstract method names
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 .

+6

All Articles