Skip to main content
 首页 » 编程设计

python之为什么我可以在 Python 中调用抽象类方法

2025年05月04日23zlslch

如果我用抽象方法定义一个抽象类:

import abc 
 
 
class A(abc.ABC): 
 
    @classmethod 
    @abc.abstractmethod 
    def foo(cls): 
        pass 

我无法实例化它(如预期的那样):

>>> A() 
TypeError: Can't instantiate abstract class A with abstract methods foo 

但是我可以毫无错误地调用它的抽象方法。

>> A.foo() 

是否在某处记录了此行为?

在 Python 3.6 和 3.7 上测试。

请您参考如下方法:

对此没有任何明确的规定。

只是 abstractmethod 装饰器的文档说:

A class that has a metaclass derived from ABCMeta cannot be instantiated unless all of its abstract methods and properties are overridden.

PEP 3119 说:

A class containing at least one method declared with this decorator that hasn't been overridden yet cannot be instantiated.

以后

Implementation: The @abstractmethod decorator sets the function attribute __isabstractmethod__ to the value True. The ABCMeta.__new__ method computes the type attribute __abstractmethods__ as the set of all method names that have an __isabstractmethod__ attribute whose value is true. It does this by combining the __abstractmethods__ attributes of the base classes, adding the names of all methods in the new class dict that have a true __isabstractmethod__ attribute, and removing the names of all methods in the new class dict that don't have a true __isabstractmethod__ attribute. If the resulting __abstractmethods__ set is non-empty, the class is considered abstract, and attempts to instantiate it will raise TypeError.

我对实现部分的解释是,@abstractmethod 从不阻止方法被调用,而只是说该类不能被实例化,子类仍然是抽象的,除非它覆盖了它的所有方法抽象方法。

所以我不会说它是设计的,但它至少是一种假定的副作用。