为什么我可以在Python中用抽象方法实例化类?

问题描述 投票:0回答:1

我注意到带有

abstractmethod
的类如果不继承自
ABC
,仍然可以被实例化。这似乎与documentation

使用这个装饰器需要类的元类是 ABCMeta 或派生自它。除非重写其所有抽象方法和属性,否则无法实例化具有从 ABCMeta 派生的元类的类。

由此我会明白

  1. 如果该类没有
    @abstractmethod
    作为元类
    ,则将 
    ABCMeta
  2. 添加到方法中将不会被 Python 接受
  3. 即使是,那个类也不能被实例化

我起草了以下示例:

from abc import abstractmethod, ABC


class TestClassOne:
    @abstractmethod
    def test_method(self):
        ...


class TestClassTwo(ABC):
    @abstractmethod
    def test_method(self):
        ...


test_object_one = TestClassOne()
test_object_two = TestClassTwo()

在 Python 3.9.13 或 3.11.3 上运行给出输出

TypeError: 无法使用抽象方法 test_method 实例化抽象类 TestClassTwo

但值得注意的是这个错误没有提到

TestClassOne
.

我是不是误解了什么,或者这可能是 Python 中的错误?

python python-3.x abstract-class abstract
1个回答
1
投票

ABCMeta
元类和
@abstractmethod
装饰器一起工作以防止实例化未实现所需方法的类。没有另一个,它们中的每一个都没有效果。

因此,如果您定义一个没有任何

@abstractmethod
装饰器的抽象基类,它允许实例化——它不是 真正 抽象。

如果你在非 ABC 中使用

@abstractmethod
,它会被忽略,因为它是实际实现强制执行的元类。这个装饰器简单地将方法注册为需要在子类中重写。

© www.soinside.com 2019 - 2024. All rights reserved.