V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
f12998765
V2EX  ›  Python

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

  •  
  •   f12998765 · 2017-08-30 17:22:53 +08:00 · 2029 次点击
    这是一个创建于 2629 天前的主题,其中的信息可能已经有所发展或是发生改变。
    如题,为什么实例属性的描述符不会自动调用描述符协议的 __get__()…这些方法?

    只能在类属性中定义描述符?
    5 条回复    2017-09-11 20:55:43 +08:00
    fangzq
        1
    fangzq  
       2017-08-31 09:50:20 +08:00
    说一下我的理解。python 文档里说,实例对象调用描述符的过程是这样的:调用 b.x 时,实际是转化为 type(b).__dict__['x'].__get__(b, type(b))执行的。如果 x 是实例属性的话,那肯定在类的 __dict__ 里找不到了,也就无法自动进行调用了。
    keakon
        2
    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
        3
    f12998765  
    OP
       2017-08-31 15:23:57 +08:00 via Android
    @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
        4
    keakon  
       2017-09-02 00:55:32 +08:00   ❤️ 1
    先想想对象和类调用时,为什么传给 __get__ 的参数要不一样。再想想类也是对象,如果要满足你的设定,__get__ 的参数就得一样了。
    f12998765
        5
    f12998765  
    OP
       2017-09-11 20:55:43 +08:00 via Android
    @keakon 谢谢
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2742 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 35ms · UTC 11:53 · PVG 19:53 · LAX 03:53 · JFK 06:53
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.