微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Python类的`__mro__`属性从何而来?

如何解决Python类的`__mro__`属性从何而来?

假设有一些课程:

class test():
    pass 

(1)Somewhere在SO上,在documentation中,我接下来读:

mro()类实例化时调用,其结果存储在__mro__中。

好的,我仍然很清楚,因为在__mro__中确实存储了一些东西:

Test.__mro__                                                         
Out[48]: (__main__.Test,object)

再次somewhere,我读到了这篇文章

要查找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. 那么,上面(1)中提到的关于documentation中存储在mro()属性中的__mro__结果的内容实际上不是这样吗?

  2. <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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。