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

为什么Python中class变量全局共享,classmethod却每个实例单独创建?

类变量与classmethod的运行逻辑差异说明

首先先修正一个常见的认知误区:classmethod本身并不会在每次生成类实例时被重新创建,它和类变量一样,仅在类定义阶段生成一次,挂载在类对象的属性字典中。你感知到的差异,本质是普通属性访问和描述符绑定逻辑的区别,具体解释如下:

1. 类变量的运行逻辑

  • 类变量属于类对象的普通数据属性,在类定义代码执行完成时就完成初始化,全生命周期内仅生成一份,存储在类的__dict__属性中
  • 当类实例访问类变量时,Python会先查找实例自身的__dict__是否有同名属性,没有的话就自动向上查找类的__dict__,直接返回类上存储的那一份变量,因此所有实例复用同一个副本,不会额外创建新对象

示例代码验证:

class TestClass:
    # 类定义阶段仅创建一次
    shared_var = "类变量"

inst1 = TestClass()
inst2 = TestClass()
# 两个实例访问到的是同一个对象
print(id(inst1.shared_var) == id(inst2.shared_var)) # 输出:True

2. classmethod的运行逻辑

  • classmethod本身是被@classmethod装饰器包装后的描述符对象,同样在类定义阶段创建完成,仅生成一份存储在类的__dict__中
  • 你观察到的「每次实例访问得到的对象不一样」,是因为访问classmethod时会触发描述符的__get__协议:该方法会返回一个临时的绑定方法对象,用于自动注入类对象作为cls参数,这个临时绑定对象每次访问都会生成新的,但原始的classmethod对象本身并没有被重新创建

示例代码验证:

class TestClass:
    @classmethod
    def test_cls_method(cls):
        pass

# 直接读取类属性字典里的原始classmethod,ID固定
print(id(TestClass.__dict__["test_cls_method"])) # 多次调用输出相同ID

inst1 = TestClass()
inst2 = TestClass()
# 从实例访问得到的是临时生成的绑定对象,ID不同
print(id(inst1.test_cls_method) == id(inst2.test_cls_method)) # 输出:False

核心差异总结

类变量是普通数据属性,访问时直接返回存储的原始对象;classmethod是描述符类型的特殊属性,访问时会触发描述符协议生成用于参数绑定的临时对象。二者的原始存储对象都仅在类定义阶段生成一次,不存在实例化时重复创建的差异。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.19 05:24:03