假设有一些类:
class Test():
pass
Run Code Online (Sandbox Code Playgroud)
mro()在类实例化时调用,其结果存储在__mro__.
好的,这对我来说仍然很清楚,因为__mro__确实存储了一些东西:
Test.__mro__
Out[48]: (__main__.Test, object)
Run Code Online (Sandbox Code Playgroud)
再一次,我在某处读到了这个:
要查找属性名称 Python 搜索:
a) 搜索在 C 处找到__dict__的所有元类__mro__的__class__。
b) 如果在步骤 a 中找到数据描述符,则调用它__get__()并退出。
c) 否则,__dict__在 C 自己的类的 中调用描述符或返回值__mro__。
d) 调用在步骤 a 中找到的非数据描述符。
e)否则,返回元类树值
我可以发现没有__mro__in Test.__dict__:
'__mro__' in Test.__dict__
Out[49]: False
Run Code Online (Sandbox Code Playgroud)
因此,根据e之前引用的条款,我想这
__mro__应该取自“元类树值”,因此取自type.__dict__
真的,还有__mro__在type.__dict__:
["mro:<method 'mro' of 'type' objects>",
"__mro__:<member '__mro__' of 'type' objects>"]
Run Code Online (Sandbox Code Playgroud)
那么上面 (1) 中提到的关于文档中mro()存储在__mro__属性中的结果并不能真正以这种方式工作?
<member '__mro__' of 'type' objects>结果如何(__main__.Test, object)?
也许你可以展示一些源代码来理解当我打电话给Test.__mro__..
“属性__mro__”是一个数据描述符,类似于property。描述符不是__mro__从 获取属性值__dict__,而是从另一个地方获取值或计算它。具体来说, a<member \'...\' of \'..\' objects>表示从 VM 内部位置 \xe2\x80\x93 获取值的描述符,这与所使用的机制__slots__相同。
>>> class Bar:\n... __slots__ = "foo",\n...\n>>> Bar.foo\n<member \'foo\' of \'Bar\' objects>\n>>> \'foo\' in Bar.__dict__\nTrue\nRun Code Online (Sandbox Code Playgroud)\n描述符被继承而不会重复,因此不会显式出现在子类上。
\n>>> class Foo(Bar):\n... __slots__ = ()\n...\n>>> Foo.foo\n<member \'foo\' of \'Bar\' objects>\n>>> \'foo\' in Foo.__dict__\nFalse\nRun Code Online (Sandbox Code Playgroud)\n这种数据描述符的精确工作member是由实现定义的。property然而,从逻辑上讲,它们的工作原理与使用内部存储相同:
class FooBar:\n def __init__(self, foo, bar):\n # attributes stored internally\n # the "_data" of a member is not visible\n self._data = [foo, bar]\n\n @property\n def foo(self):\n return self._data[0]\n\n @foo.setter\n def foo(self, value):\n self._data[0] = value\n\n @property\n def bar(self):\n return self._data[1]\n\n @bar.setter\n def bar(self, value):\n self._data[1] = value\nRun Code Online (Sandbox Code Playgroud)\n