首页 新闻 会员 周边

看懂装饰器4

0
[已关闭问题] 关闭于 2026-06-26 11:26

这里其实发生了 两次“绑定” 动作,分别对应两个不同的 self :
第一次绑定: self.call (这是你最关心的)
● 谁绑定了谁?
Python 自动把 Decorator 的实例(即 self ) 绑定到了 call 方法上。
● 怎么实现的?
当你写 self.call 时,Python 发现 call 是 Decorator 类的一个普通函数。根据描述符协议,Python 自动 执行了默认的 function.get(self, Decorator) 。
● 结果是什么?
生成了一个 绑定方法对象。这个对象内部已经“锁死”了第一个参数必须是当前的 Decorator 实例。
● 结论:
这一步 不需要 你手动用 partial 去绑定 self 。Python 在解析 self.call 这个属性访问时,就已经帮你把 Decorator 的 self 绑定好了。

第二次绑定: partial(..., instance) (这是为了解决 c 的问题)
● 为什么要用 partial ?
因为 call 的定义是 def call(self, *args, **kwargs): 。
经过第一步绑定后,它的签名变成了类似 bound_method(*args, **kwargs) ,其中 self (Decorator 实例)已经被填进去了。
但是! method 函数原本还需要接收 c (即 instance )作为第一个参数。现在 call 被直接返回给外部调用,如果不处理, c 就会丢失。
● partial 干了啥?
它把 instance (即 c ) 强行塞进了 call 的参数列表的最前面。
● 结果是什么?
最终返回的对象,调用时会自动把 c 传给 call 的 *args 的第一个位置。

总结你的疑问

“自定义里面没有手动绑定啊?”
事实是:
1. 对于 Decorator 的 self :你 没有 手动绑定,是 Python 在读取 self.call 时 自动 帮你绑定的(通过默认的函数描述符机制)。
2. 对于 cls 的实例 c :因为你自己写了 get ,Python 不再自动帮你绑定 c 到原始函数 func 上。所以你必须 手动 用 partial 把 c 塞进调用链里。

问题补充:
  1.  

*Tesla*的主页 *Tesla* | 老鸟四级 | 园豆:2074
提问于:2026-06-26 11:25
< >
分享
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册