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

Python类中列表行为异常的原因及实现机制咨询

Python中列表与类结合的共享实例问题解析

你观察到的现象本质是可变对象在Python中的特殊处理逻辑,下面分场景拆解实现机制,并说明设计目的:

一、带默认列表参数的构造方法:实例共享列表的原因

Python的函数默认参数是在函数定义阶段就创建完成,而非每次调用函数时重新生成。当你定义def __init__(self, money=[200]):时,[200]这个列表对象在类被加载时就已经固定在内存中。

每次调用BasicClass()(不传参数)时,self.money都会指向这个预先创建好的同一个列表实例。因此两个对象的money属性本质是对同一个列表的引用,调用append方法会直接修改这个共享列表。

你可以通过打印内存地址验证:

print(id(object.money), id(object_2.money))  # 输出两个相同的内存地址

二、类变量版本:实例共享列表的原因

类变量是属于类本身的属性,所有该类的实例在未定义同名实例变量时,访问的都是类级别的同一个对象。

在这个例子中,BasicClass.money是类级别的列表对象,self.money.append(value)并没有给实例创建专属的money属性,而是直接修改了类变量指向的列表。因此所有实例访问self.money时,都会看到这个被修改过的共享列表。

验证代码:

print(id(object.money), id(BasicClass.money))  # 输出相同的内存地址

三、无默认参数版本:实例各自拥有列表的原因

每次创建实例时,你都传入了新的列表[100]——也就是每次调用BasicClass([100])都会生成一个全新的列表对象,self.money指向这个新对象。两个实例的money引用的是不同的列表,修改自然互不影响。

设计目的

  1. 性能优化:默认参数仅在定义时创建一次,避免了每次调用函数重复创建相同可变对象的开销,节省内存与初始化时间。
  2. 类变量的语义匹配:类变量的设计初衷就是承载类的共享状态,比如统计实例总数、共享全局配置等,这种共享行为符合“类级共享数据”的语义。

避免共享的正确写法

修复默认参数场景

将默认值设为None,在__init__内动态创建新列表:

class BasicClass:
    def __init__(self, money=None):
        self.money = money if money is not None else [200]
    def add_money(self, value):
        self.money.append(value)

修复类变量场景

在__init__中创建实例专属的列表变量:

class BasicClass:
    def __init__(self):
        self.money = [200]  # 每个实例初始化独立列表
    def add_money(self, value):
        self.money.append(value)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 13:24:53