实例方法通过“实例点调用”自动绑定self,@classmethod按实际调用类绑定cls,@staticmethod无绑定;三者均依赖描述符协议实现隐式参数注入,动态绑定方法可安全作回调。

类方法执行时的自动绑定,核心在于让 Python 在调用时“知道该传谁”——不是靠手动传参,而是靠调用方式触发描述符协议,完成隐式参数注入。掌握这个机制,能写出更清晰、不易出错的面向对象代码。
实例方法:self 自动绑定靠的是“实例点调用”
只要通过实例调用(obj.method()),Python 就会把 obj 自动作为第一个参数传给方法。这背后是函数对象的 __get__ 方法被触发,返回一个绑定了该实例的可调用对象。
- 写法正确:
obj.say_hello()→ 自动传入obj作为self - 写法错误:
MyClass.say_hello()→ 不自动传参,必须显式写成MyClass.say_hello(obj) - 验证绑定状态:
print(obj.method)会显示<bound method ...></bound>;而print(MyClass.method)显示<function ...></function>
@classmethod:cls 绑定不看调用者是谁,只看实际类
用 @classmethod 修饰的方法,无论通过实例还是类调用,第一个参数都是类本身(cls),且 cls 指向的是**实际触发调用的类**,支持继承场景下的多态行为。
-
MyClass.create()→cls是MyClass -
SubClass.create()→cls是SubClass(不是MyClass) - 适合做工厂方法、类级配置、替代构造器等不依赖具体实例的逻辑
@staticmethod:彻底解除绑定,只是挂名在类里的普通函数
静态方法不参与任何绑定逻辑。它既不接收 self,也不接收 cls,调用时和模块顶层函数完全一样。
-
obj.helper(x, y)和MyClass.helper(x, y)效果一致 - 本质是把工具函数组织进类命名空间,语义上归属该类,但运行时无关联
- 如果函数内部需要访问实例或类状态,就不要用
@staticmethod
动态绑定行为传递:用已绑定方法作回调很安全
当你把 obj.method(不加括号)赋值或传参时,得到的是一个已绑定的对象,自带上下文。后续任意位置调用它,都始终作用于原始实例。
- GUI 注册事件处理器:
button.on_click = processor_a.process→ 点击永远更新processor_a的状态 - 异步任务调度:
loop.call_later(1.0, worker.run)→run执行时仍持有worker的全部属性 - 注意:不能对动态添加的函数(如
obj.f = lambda: ...)期待自动绑定,只有类体中定义的函数才走描述符流程











