问题描述
假设有一些课程:
class test():
pass
(1)Somewhere在SO上,在documentation中,我接下来读:
好的,我仍然很清楚,因为在__mro__
中确实存储了一些东西:
Test.__mro__
Out[48]: (__main__.Test,object)
要查找Python搜索的属性名称:
a)在以下位置找到的__dict__
上搜索所有元类的__mro__
C的__class__
。
b)如果在步骤a中找到了数据描述符,请调用其__get__()
然后退出。
c)否则,调用描述符或在__dict__
中返回一个值 C自己的__mro__
上的班级。
d)调用在步骤a中找到的非数据描述符。
e)否则,返回元类树值
我发现__mro__
中没有Test.__dict__
:
'__mro__' in Test.__dict__
Out[49]: False
因此,根据先前引文的e
子句,我想
__mro__
应该取自“元类树值”,因此应取自type.__dict__
真的,__mro__
中有type.__dict__
:
["mro:<method 'mro' of 'type' objects>","__mro__:<member '__mro__' of 'type' objects>"]
-
那么,上面(1)中提到的关于documentation中存储在
mro()
属性中的__mro__
结果的内容实际上不是这样吗? -
<member '__mro__' of 'type' objects>
如何变成(__main__.Test,object)
?
也许您可以显示一些源代码来了解我打Test.__mro__
时的真实情况。
解决方法
__mro__
“属性”是data descriptor,类似于property
。描述符不是从__mro__
获取__dict__
属性值,而是从另一个位置获取或计算该值。具体来说,<member '...' of '..' objects>
表示从VM内部位置获取值的描述符–这与mechanism used by __slots__
相同。
>>> class Bar:
... __slots__ = "foo",...
>>> Bar.foo
<member 'foo' of 'Bar' objects>
>>> 'foo' in Bar.__dict__
True
描述符是无重复继承的,因此不会显式出现在子类上。
>>> class Foo(Bar):
... __slots__ = ()
...
>>> Foo.foo
<member 'foo' of 'Bar' objects>
>>> 'foo' in Foo.__dict__
False
此类member
数据描述符的精确工作由实现定义。但是,从逻辑上讲,它们与使用内部存储器的property
相同:
class FooBar:
def __init__(self,foo,bar):
# attributes stored internally
# the "_data" of a member is not visible
self._data = [foo,bar]
@property
def foo(self):
return self._data[0]
@foo.setter
def foo(self,value):
self._data[0] = value
@property
def bar(self):
return self._data[1]
@bar.setter
def bar(self,value):
self._data[1] = value