7

最近我阅读了关于 Python 描述符的官方 HOW-TO,它实际上来自于Raymond Hettinger 很久以前写的一篇文章。但读了几遍后,我仍然对它的某些部分感到困惑。我将引用一些段落,然后是我的困惑和问题。


如果实例的字典中有一个与数据描述符同名的条目,则数据描述符优先。如果实例的字典具有与非数据描述符同名的条目,则字典条目优先。

  • 上课也是这样吗?如果一个类的字典有一个与数据/非数据描述符同名的条目,那么它的优先级链是什么?

对于物体来说,机器在object.__getattribute__()其中转化b.xtype(b).__dict__['x'].__get__(b, type(b))。该实现通过优先链进行工作,该优先链赋予数据描述符优先于实例变量,实例变量优先于非数据描述符,并分配最低优先级(__getattr__()如果提供)。

对于类,机器在type.__getattribute__()其中转换B.xB.__dict__['x'].__get__(None, B).

  • 上面两段讲述了在属性访问时自动调用描述符的过程。b.x它列出了实例 ( ) 和类 ( )访问属性之间的区别B.x。但是,这是我的困惑:
    • 如果类或实例的属性不是描述符,那么转换(即转换b.xtype(b).__dict__['x'].__get__(b, type(b))B.xB.__dict__['x'].__get__(None, B))还会继续吗?在此类或实例的字典中直接返回属性是否更简单?
    • 如果一个实例的字典中有一个与非数据描述符同名的条目,根据第一个引号中的优先规则,字典条目优先,这时候转换还会继续吗?还是只返回其dict中的值?

非数据描述符提供了一种简单的机制,可以将通常的绑定函数模式更改为方法。

  • 是否选择了非数据描述符,因为函数/方法只能获取但不能设置
  • 将函数绑定到方法的底层机制是什么?由于类字典将方法存储为函数,如果我们分别使用类及其实例调用相同的方法,底层函数如何判断它的第一个参数是否应该是self呢?

函数有一个__get__()方法,因此当作为属性访问时它们可以转换为方法。非数据描述符将obj.f(*args)调用转换为f(obj, *args). 调用klass.f(*args)变为 f(*args)。

  • 非数据描述符如何将obj.f(*args)调用转换为f(obj, *args)
  • 非数据描述符如何将klass.f(*args)调用转换为f(*args)
  • 上述两种转换的底层机制是什么?为什么类和实例之间存在差异?
  • __get__()在上述情况下角色方法的作用是什么?
4

1 回答 1

2

上课也是这样吗?如果一个类的字典有一个与数据/非数据描述符同名的条目,那么它的优先级链是什么?

不,如果在超类和子类中都定义了属性,则完全忽略超类值。

如果类或实例的属性不是描述符,那么转换(即,将 bx 转换为type(b).__dict__['x'].__get__(b, type(b))和 Bx 转换为B.__dict__['x'].__get__(None, B))仍然进行吗?

不,它直接返回从类的__dict__. 或者等效地,是的,如果您假设所有对象默认都有一个__get__()忽略其参数并返回的方法self

如果一个实例的字典中有一个与非数据描述符同名的条目,根据第一个引号中的优先规则,字典条目优先,这时候转换还会继续吗?或者只是返回其字典中的值?

您引用的段落(可能在其他地方写下来)中不清楚的是,当b.x决定 return时b.__dict__['x'],无论如何__get__都会调用 no 。当__get__语法b.xB.x决定返回一个存在于字典中的对象时,就会准确地调用 。

选择非数据描述符是因为函数/方法只能获取,不能设置吗?

是的:它们是 Python 中“旧式”类模型的概括,您可以说B.f = 42即使f是存在于 B 类中的函数对象。这使得函数对象可以被不相关的对象覆盖。另一方面,数据描述符具有不同的逻辑以支持property.

将函数绑定到方法的底层机制是什么?由于类字典将方法存储为函数,如果我们分别使用一个类和它的实例调用同一个方法,底层函数如何判断它的第一个参数是否应该是 self 呢?

要理解这一点,您需要牢记“方法对象”。语法b.f(*args)等价于(b.f)(*args),即两步。第一步调用f.__get__(b);这将返回一个存储 b 和 f 的方法对象。第二步调用方法对象,然后通过添加 b 作为额外参数来调用原始 f。这是不会发生的B.f,因为B.fief.__get__(None, B)只是 f(在 Python 3 中)。__get__这是在函数对象上设计特殊方法的方式。

于 2013-04-19T14:23:31.780 回答