You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Python不会调用另一个描述符内部的函数描述符?

问题解析:为何描述符返回函数时未触发绑定方法行为

你遇到的核心问题是Python属性查找的阶段逻辑:当你通过描述符的__get__方法返回一个对象时,这个对象不会再被当作类属性触发自身的描述符行为——因为属性查找的描述符处理只发生在查找类/实例属性的初始阶段,而不是返回结果的二次处理阶段。

具体拆解

  1. 属性访问的流程:
    当执行example.non_method时,Python会先在example的__dict__里找non_method,找不到就去Example类的__dict__里找。此时non_method是Identity实例(因为用了装饰器),而Identity实现了__get__,所以会调用Identity.__get__(example, Example)。

  2. Identity.__get__的返回值处理:
    你的__get__直接返回self.value(也就是原non_method函数)。这时候,这个函数对象会直接作为属性访问的结果返回,不会再触发它自身的__get__方法——因为只有当这个函数是作为类属性被直接查找时,才会触发它的描述符逻辑(绑定成方法)。而这里它是从另一个描述符的返回值里拿出来的,不属于类属性查找的范畴。

  3. 手动触发绑定的区别:
    你手动调用example.non_method.__get__(...)能得到绑定方法,是因为你主动触发了函数的描述符逻辑,但正常属性访问中,Python不会为描述符返回的对象自动做这一步。

验证逻辑

如果想让返回的函数触发绑定行为,你需要在Identity.__get__里手动调用函数的__get__方法,比如:

def __get__(self, obj, objtype=None):
    # 主动触发函数的描述符绑定逻辑,绑定到obj实例
    return self.value.__get__(obj, objtype)

此时再访问example.non_method,就会得到绑定方法了。

总结

描述符的__get__返回的对象,只是属性访问的最终结果,不会再经过描述符的处理流程。函数的绑定行为是它作为类属性被访问时才会触发的,而不是作为任意对象返回时自动触发的。

内容的提问来源于stack exchange,提问作者schuelermine

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 18:43:10