为什么描述符不能定义为实例属性

2017-08-30 17:22:53 +08:00
 f12998765
如题,为什么实例属性的描述符不会自动调用描述符协议的 __get__()…这些方法?

只能在类属性中定义描述符?
1916 次点击
所在节点    Python
5 条回复
fangzq
2017-08-31 09:50:20 +08:00
说一下我的理解。python 文档里说,实例对象调用描述符的过程是这样的:调用 b.x 时,实际是转化为 type(b).__dict__['x'].__get__(b, type(b))执行的。如果 x 是实例属性的话,那肯定在类的 __dict__ 里找不到了,也就无法自动进行调用了。
keakon
2017-08-31 09:50:24 +08:00
https://docs.python.org/3/howto/descriptor.html#invoking-descriptors

For objects, the machinery is in object.__getattribute__() which transforms b.x into type(b).__dict__['x'].__get__(b, type(b)). The implementation works through a precedence chain that gives data descriptors priority over instance variables, instance variables priority over non-data descriptors, and assigns lowest priority to __getattr__() if provided. The full C implementation can be found in PyObject_GenericGetAttr() in Objects/object.c.

For classes, the machinery is in type.__getattribute__() which transforms B.x into B.__dict__['x'].__get__(None, B).
f12998765
2017-08-31 15:23:57 +08:00
@fangzq @keakon 感谢

我的疑问就是转换这一步,为什么要为转换为 type(b).__dict__['x'].__get__(b, type(b)) ,而不是直接调用 b.__dict__['x'].__get__(b, type(b))

把 x 定义为实例属性,肯定可以在 b 的 __dict__ 中找到,但是输出 b.x 时却不会触发 b.__dict__['x'].__get__(b, type(b)) 这样的调用

我知道这样的转换是在 object.__getattribute__()/type .__getattribute__() 写好的,只是想不明白为什么这样,有点卡壳

如果是为了数据描述符和非数据描述符的优先级,那区分它们有什么意义吗?

你们有什么想法,可以点一点我,感谢

或许我应该去看看 PEP
keakon
2017-09-02 00:55:32 +08:00
先想想对象和类调用时,为什么传给 __get__ 的参数要不一样。再想想类也是对象,如果要满足你的设定,__get__ 的参数就得一样了。
f12998765
2017-09-11 20:55:43 +08:00
@keakon 谢谢

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/386944

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX