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

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的。

解决方法

如果不想让函数被自动绑定实例,有几种方式:

  1. 将函数转为静态方法:
    @staticmethod
    def some_function(*args, **kwargs):
        print(args, kwargs)
        print("No args automatically filled now!")
    
    class B(A):
        METHOD = some_function
    
    或者在赋值时包装:
    class B(A):
        METHOD = staticmethod(some_function)
    
  2. 直接调用类上的函数,绕过实例绑定:
    def run(self):
        self.__class__.METHOD()
    
  3. 将METHOD设为实例变量,在__init__中赋值:
    class B(A):
        def __init__(self):
            self.METHOD = some_function
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 03:07:38