__abstractmethods__ 和 AttributeError

8 投票
1 回答
3204 浏览
提问于 2025-04-18 14:27

我在玩一个叫做 dir() 的内置函数时,注意到了这个:

>>> dir(type)
['__abstractmethods__', '__base__', '__bases__', '__basicsize__', '__call__', '__class__', '__delattr__', '__dict__', '__dictoffset__', '__dir__', '__doc__', '__eq__', '__flags__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__instancecheck__', '__itemsize__', '__le__', '__lt__', '__module__', '__mro__', '__name__', '__ne__', '__new__', '__prepare__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasscheck__', '__subclasses__', '__subclasshook__', '__text_signature__', '__weakrefoffset__', 'mro']
>>> type.__abstractmethods__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: __abstractmethods__
>>> list.__abstractmethods__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: __abstractmethods__

我不太明白,为什么它出现在列表里,但我却会收到这样的错误呢?

1 个回答

9

__abstractmethods__ 是一个特殊的工具,叫做 描述符,它用来支持 抽象基类。简单来说,它就像一个空的容器(默认是空的),如果你试图访问它,程序会报错。最重要的是,这个工具是 CPython(Python的一种实现)处理抽象方法的内部细节。

这个属性的作用是跟踪哪些方法是抽象的,这样如果某个实例没有提供具体的实现,就不能创建这个实例:

>>> import abc
>>> class FooABC(metaclass=abc.ABCMeta):
...     @abc.abstractmethod
...     def bar(self):
...         pass
... 
>>> FooABC.__abstractmethods__
frozenset({'bar'})
>>> class Foo(FooABC): pass
... 
>>> Foo()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class Foo with abstract methods bar

abc.ABCMeta 的实现中,会设置 __abstractmethods__ 这个属性,而 type() 会用它来检查是否有任何应该被实现但实际上没有实现的抽象方法。

撰写回答