为啥不在实例属性查找中搜索元类的属性?
Posted
技术标签:
【中文标题】为啥不在实例属性查找中搜索元类的属性?【英文标题】:Why aren't metaclass's attributes searched in instance attribute lookups?为什么不在实例属性查找中搜索元类的属性? 【发布时间】:2016-12-01 16:59:27 【问题描述】:根据 Python 2.7.12 文档,3.4.2.3。调用描述符¶:
属性访问的默认行为是获取、设置或删除 对象字典中的属性。例如,
a.x
有一个 以a.__dict__['x']
开头的查找链,然后type(a).__dict__['x']
,并继续通过基类type(a)
不包括元类。
但是为什么排除元类呢?
如果你不断地调用type(self)
,不管self
是一个实例对象还是类型对象,你最终都会得到<type 'type'>
。所以我不明白为什么元类享有这种“特权”。
顺便说一句,我对这个引用有点困惑:例如对象,使用object.__getattribute__
,所以我认为查找链应该是这样的:
a.__dict__['x']
type(a).__dict__['x']
b.__dict__[x]
为b
在type(a).__mro__
type(b).__dict__[x]
为b
在type(a).__mro__
c.__dict__[x]
为c
在type(b).__mro__
......
我说的对吗?
【问题讨论】:
我看到你正在试验元类和属性访问——你有什么理由不使用 Python 3?今天几乎所有项目都可以使用 Python 3,并且有很多特性/更改没有进入 Python2 @jsbueno 嗯...为了兼容性,我猜。我的大学(实际上是我的同学,我们正在一起做一个项目。)建议我先学习Python2,因为很多模块还没有支持Python3,而且他们可能在不久的将来不支持它。我的实验是为了更好地理解 Python 在后台是如何工作的,如果有一天我决定改用 Python3,它们会很有帮助,对吧? 我认为“许多模块还没有 Python 3 支持”从 2015 年开始就不正确了。现在最重要的事情在 Python3 中确实有效,最重要的是,对于您正在寻求的深入理解,我会说 Python3 更相关。 Python 的 s2 end of line 计划在 2020 年。如果你今天开始一个项目,那就是 3 年之前必须迁移它 - 我不会说它值得。 @jsbueno 好吧,也许我们真的应该使用 Python 3,因为它是未来。 【参考方案1】:这是因为属性查找搜索type(a)
(type(a).__mro__
) 的所有碱基,而不是type(a)
(type(type(a))
) 的所有类型。
另外,type(self)
不是连续调用的,所以查找链如下所示:
a.__dict__['x']
type(a).__dict__['x']
b.__dict__[x] for b in type(a).__mro__
raise AttributeError
正如@jsbueno 在评论中明智地指出的那样,第二步实际上包含在第三步中。这是因为对于任何类,假设类C
,C
本身正是C.__mro__
中的第一项。
【讨论】:
其实第二步是包含在第三步中的——要了解会发生什么,type(a).__dict__['x']
验证包含在b.__dict__[x] for b in type(a).__mro__
中
@jsbueno 是的,你是对的。类C
本身正是C.__mro__
中的第一项。答案已编辑。以上是关于为啥不在实例属性查找中搜索元类的属性?的主要内容,如果未能解决你的问题,请参考以下文章