今天我发现python对象没有__mro_entries__可以用作基类。
例子:
class Base:
def __init__(self, *args):
self.args = args
def __repr__(self):
return f'{type(self).__name__}(*{self.args!r})'
class Delivered(Base):
pass
b = Base()
d = Delivered()
class Foo(b, d):
pass
print(type(Foo) is Delivered)
print(Foo)
Run Code Online (Sandbox Code Playgroud)
True
Delivered(*('Foo', (Base(*()), Delivered(*())), {'__module__': '__main__', '__qualname__': 'Foo'}))
Run Code Online (Sandbox Code Playgroud)
结果Foo将是类的实例Delivered,并且它不是有效的类型。
我确实理解以下用例,__mro_entries__但是使用对象而不__mro_entries__作为基类的用例是什么。这是Python的一个错误吗?
TL;DR 不是错误,而是对该class语句的极端滥用。
一条class语句相当于对元类的调用。由于缺乏显式metaclass关键字参数,元类必须从基类推断。这里,“类”的“元类”b是Base,而 的元类d是Delivered。由于每个元类都是公共元类 ( ) 的非严格子类Base,Delivered因此被选为更具体的元类。
>>> Delivered('Foo', (b, d), {})
Delivered(*('Foo', (Base(*()), Delivered(*())), {}))
Run Code Online (Sandbox Code Playgroud)
Delivered可以用作元类,因为它接受该class语句期望元类接受的相同参数:类型名称的字符串、父类的序列以及用作命名空间的映射。在这种情况下,Delivered不使用它们来创建类型;它只是打印参数。
因此,Foo绑定到 的实例Delivered,而不是类型。类也是如此Foo,只是在它是由语句生成的意义上class:它绝对不是类型。
>>> issubclass(Foo, Delivered)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: issubclass() arg 1 must be a class
>>> Foo()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'Delivered' object is not callable
Run Code Online (Sandbox Code Playgroud)