Python子类中类变量METHOD被视为类方法的设计原因问询
为什么通过实例访问类变量中的普通函数会自动传入实例作为参数?
在Python 3.10中尝试通过类变量METHOD为子类定制行为时,发现调用METHOD时会自动传入类实例,就像类方法一样。核心疑问是:为什么普通函数会被当作类方法处理?
代码示例
def some_function(*args, **kwargs): print(args, kwargs) print("Why are any args being filled at all?!??!!") class A(object): METHOD = None def run(self): self.METHOD() class B(A): METHOD = some_function # 创建实例并调用run方法 instance_of_b = B() instance_of_b.run()
输出结果
(<__main__.B object at 0x7f532970f340>,) {} Why are any args being filled at all?!??!!
原因解释
这是Python的绑定机制导致的:
- 当你通过
self.METHOD访问类变量中的函数时,Python会自动将这个函数绑定到当前实例,生成一个绑定方法(bound method)。 - Python的方法调用逻辑是统一的:只要通过
obj.attr()的形式调用可调用对象,且attr是类层面定义的函数(不管是类方法、实例方法还是普通函数赋值的类变量),Python都会自动把obj作为第一个参数传入,以此保持实例方法调用的一致性——比如类中定义的实例方法就是靠这个机制自动传入self的。
解决方法
如果不想让函数被自动绑定实例,有几种方式:
- 将函数转为静态方法:
或者在赋值时包装:@staticmethod def some_function(*args, **kwargs): print(args, kwargs) print("No args automatically filled now!") class B(A): METHOD = some_functionclass B(A): METHOD = staticmethod(some_function) - 直接调用类上的函数,绕过实例绑定:
def run(self): self.__class__.METHOD() - 将
METHOD设为实例变量,在__init__中赋值:class B(A): def __init__(self): self.METHOD = some_function
内容的提问来源于stack exchange,提问作者user1639926
相关产品推荐
相关产品推荐

