__abstractmethods__ 和 AttributeError
我在玩一个叫做 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()
会用它来检查是否有任何应该被实现但实际上没有实现的抽象方法。