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

Python中类属性为字典时新实例未重置的原因探究

类属性中可变与不可变对象的行为差异解释

示例结果回顾

  • 第一个示例输出:1
  • 第二个示例输出:3

原因解析

第一个示例(不可变类属性:整数)

class StatsCourseBuilder():
    test = 0

novoA = StatsCourseBuilder()
novoA.test += 1
novoA.test += 1

novoB = StatsCourseBuilder()
print(novoB.test) # 输出1
novoB.test += 1

整数是不可变类型,当执行novoA.test +=1时,Python无法修改原整数对象的值,会创建一个新的整数对象,并将这个新对象绑定到novoA的实例属性test上。此时novoA的test已经和类属性的test无关,是实例独有的属性。

而novoB没有创建自己的实例属性test,访问的始终是类属性的test=0,执行novoB.test +=1后,实例属性test的值为1,所以打印结果是1。

第二个示例(可变类属性:字典)

class StatsCourseBuilder():
    test = {'name' : 0}

novoA = StatsCourseBuilder()
novoA.test['name'] += 1
novoA.test['name'] += 1

novoB = StatsCourseBuilder()
print(novoB.test['name']) # 输出3
novoB.test['name'] += 1

字典是可变类型,当执行novoA.test['name'] +=1时,并没有创建新的字典对象,而是直接在原类属性的字典内部修改name对应的值。因为所有实例共享类属性的可变对象,所以novoA的修改会直接反映到类属性上,novoB访问的还是同一个字典对象。

novoA修改两次后,字典中name的值变为2,novoB再执行一次加1操作,值就变成3,所以打印结果是3。

问题解答

字典作为类属性的值确实是导致该现象的核心原因。本质是可变对象与不可变对象在类属性中的行为差异:

  • 不可变类属性:修改操作会触发实例属性的创建,实例不再共享类属性的值
  • 可变类属性:原地修改操作会直接改变共享的类属性对象,所有实例都会受影响

参考文档内容(翻译自Python官方文档)

在Python中,类变量是所有类实例共享的属性,而实例变量是每个实例独有的属性。当你尝试修改不可变类型的类变量时,实际上会为当前实例创建一个同名的实例变量,后续对该属性的访问都会指向这个实例变量;而对于可变类型的类变量,由于可以原地修改其内容,所有实例都会共享这个可变对象的修改结果。

内容的提问来源于stack exchange,提问作者José Victor

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 18:42:35