首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python类的`__mro__`属性来自何处?

Python类的`__mro__`属性来自何处?
EN

Stack Overflow用户
提问于 2020-08-12 10:41:50
回答 1查看 1K关注 0票数 6

假设有一些课程:

代码语言:javascript
复制
class Test():
    pass 

(1)某处 on SO,在文档中,我接着读到:

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

好吧,这对我来说还是很清楚的,因为在__mro__中有一些东西是真正存储的:

代码语言:javascript
复制
Test.__mro__                                                         
Out[48]: (__main__.Test, object)

再一次,某处我读到了以下内容:

要查找属性名称,Python搜索: (A)在C‘s __dict____mro__上搜索所有元类的__mro__。 B)如果在步骤a中找到数据描述符,则调用其__get__()并退出。 否则,调用描述符或在C自己的__dict__上返回类的__mro__中的值。 D)调用步骤a中找到的非数据描述符。 (E)否则,返回元类树值。

我可以发现在__mro__中没有Test.__dict__

代码语言:javascript
复制
'__mro__' in Test.__dict__                                           
Out[49]: False

因此,对于前面引号中的e子句,我想__mro__应该从“元树值”中提取,因此应该从type.__dict__中提取。

真的,在__mro__中有type.__dict__

代码语言:javascript
复制
["mro:<method 'mro' of 'type' objects>",
"__mro__:<member '__mro__' of 'type' objects>"]
  1. 那么,在(1)中提到的关于存储在来自mro()__mro__属性中的__mro__结果的内容实际上并不是这样的?
  2. <member '__mro__' of 'type' objects>(__main__.Test, object)的结果如何

也许您可以展示一些源代码来了解当我调用Test.__mro__时发生了什么。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-08-12 11:45:32

__mro__“属性”是一个数据描述符,类似于property。描述符没有从__mro__属性值中获取__dict__属性值,而是从另一个地方获取或计算该值。具体而言,<member '...' of '..' objects>表示从VM(内部位置)获取值的描述符--这是同一个__slots__

代码语言:javascript
复制
>>> class Bar:
...     __slots__ = "foo",
...
>>> Bar.foo
<member 'foo' of 'Bar' objects>
>>> 'foo' in Bar.__dict__
True

描述符是在没有重复的情况下继承的,因此不会显式地出现在子类上。

代码语言:javascript
复制
>>> class Foo(Bar):
...     __slots__ = ()
...
>>> Foo.foo
<member 'foo' of 'Bar' objects>
>>> 'foo' in Foo.__dict__
False

这种member数据描述符的精确工作是定义的。但是,从逻辑上讲,它们与使用内部存储的property一样工作:

代码语言:javascript
复制
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
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63374826

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档