Python 阻止为具有抽象方法的类创建实例。所以只是你有一个实例意味着你没有抽象方法。
但是,您必须使用 ABCMeta metaclass 才能正确触发此行为:
class Base(metaclass=abc.ABCMeta):
@abc.abstractmethod
def someAbstractMethod(self):
raise NotImplementedError("Not implemented yet.")
您也可以从abc.ABC 继承以通过基类获取相同的元类。
如果您想查看一个类 可能列出了哪些抽象方法,请使用__abstractmethods__ 属性;它是一组仍然抽象的所有名称:
>>> import abc
>>> class Base(metaclass=abc.ABCMeta):
... @abc.abstractmethod
... def someAbstractMethod(self):
... raise NotImplementedError("Not implemented yet.")
...
>>> class Subclass(Base):
... def someAbstractMethod(self):
... some_operations
...
>>> Base.__abstractmethods__
frozenset({'someAbstractMethod'})
>>> Subclass.__abstractmethods__
frozenset()
@abc.abstractmethod 装饰器所做的只是在函数对象上设置一个__isabstractmethod__ 属性;然后是元类使用这些属性。
因此,如果您挖掘得太深或正在使用忘记使用 ABCMeta 元类的第三方库,您可以测试这些属性:
>>> class Base: # note, no metaclass!
... @abc.abstractmethod
... def someAbstractMethod(self):
... raise NotImplementedError("Not implemented yet.")
...
>>> getattr(Base().someAbstractMethod, '__isabstractmethod__', False)
True
如果您需要“修复”此类损坏的抽象基类,您需要子类化并混入ABCMeta,并将__abstractmethods__frozenset 添加到您继承自的类中:
BaseClass.__abstractmethods__ = frozenset(
name for name, attr in vars(BaseClass).items()
if getattr(attr, '__isabstractmethod__', False))
class DerivedClass(BaseClass, metaclass=abc.ABCMeta):
# ...
现在DerivedClass 是一个适当的 ABC 派生类,其中任何抽象方法都可以正确跟踪和执行。