【问题标题】: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]btype(a).__mro__
  • type(b).__dict__[x]btype(a).__mro__
  • c.__dict__[x]ctype(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,因为它是未来。

标签: python attributes metaclass python-internals getattribute


【解决方案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 在评论中明智地指出的那样,第二步实际上包含在第三步中。这是因为对于任何类,假设类CC 本身正是C.__mro__ 中的第一项。

【讨论】:

  • 其实第二步是包含在第三步中的——要了解会发生什么,type(a).__dict__['x']验证包含在b.__dict__[x] for b in type(a).__mro__
  • @jsbueno 是的,你是对的。类C 本身正是C.__mro__ 中的第一项。答案已编辑。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-12-09
  • 2021-12-26
  • 2019-05-17
  • 2016-09-07
  • 1970-01-01
  • 2017-12-08
相关资源
最近更新 更多