我正在使用Python3.3并注意到以下内容:元类与用户定义的类和多重继承完美配合,但是当一个类继承自内置类型(例如list,tuple,complex ...)时意外地改变了。
首先,一个行为正确的例子:
from abc import ABCMeta, abstractmethod
class A(metaclass=ABCMeta):
@abstractmethod
def say_hello(self):
print("hello")
class B:
pass
class C(A, B):
pass
由于抽象方法say_hello尚未被覆盖,因此在实例化C类时这是正确的结果:
>>> c = C()
Traceback (most recent call last):
File "<pyshell#42>", line 1, in <module>
c=C()
TypeError: Can't instantiate abstract class C with abstract methods say_hello
我也用B metaclass
尝试了这个,它运行正常。
现在是奇怪的部分。让我们用内置的(在这个例子中list
)替换B:
from abc import ABCMeta, abstractmethod
class A(metaclass=ABCMeta):
@abstractmethod
def say_hello(self):
print("hello")
class C(A, list):
pass
实例化工作,这不是人们应该期待的:
>>> c = C()
>>>
更糟糕的是,抽象方法可以在没有任何super()
的情况下调用:
>>> c.say_hello()
hello
我做错了什么?如果这是一个记录在案的行为,我会很感激,如果有人引用它。
修改 我只是添加评论,因为后果比我预期的更糟:
>>> import numbers
>>> b = 2
>>> isinstance(b, numbers.Integral)
True
>>> isinstance(b, int)
True
>>> b.real
2
>>> class A(numbers.Integral, int):
pass
>>> a = A()
>>> isinstance(a, int)
True
>>> isinstance(a, numbers.Integral)
True
>>> a.real
Traceback (most recent call last):
File "<pyshell#114>", line 1, in <module>
a.real
File "C:\Python33\lib\numbers.py", line 258, in real
return +self
File "C:\Python33\lib\numbers.py", line 89, in __pos__
raise NotImplementedError
NotImplementedError