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

为何修改Python类的单个实例会导致所有实例及原数组发生变化?

Python中Numpy数组作为类属性的共享修改问题解答

问题场景

你遇到的情况是:用同一个Numpy数组初始化两个类实例的属性后,修改其中一个实例的属性,另外一个实例的属性甚至原数组都跟着变了,但用标量就不会有这个问题。你的测试脚本和输出如下:

测试脚本

import numpy as np 
s = np.array([1,2,3]) 
class test_class: 
    def __init__(self,vv): 
        self.v = vv 
    def add(self,h,i): 
        aux = self.v 
        aux[i] += h 
        self.v = aux 
tt1=test_class(s) 
tt2=test_class(s) 
tt1.add(1,0) 
print('s = ', s) 
print('tt1.v = ',tt1.v) 
print('tt2.v = ',tt2.v)

输出结果

s = [2 2 3] 
tt1.v = [2 2 3] 
tt2.v = [2 2 3]

原因解析

这本质是Python中可变对象与引用传递的特性在起作用,核心区别在于Numpy数组(可变对象)和标量(不可变对象)的处理方式:

  • Numpy数组是可变对象:这类对象的特点是可以在原地修改内容,不需要创建新对象。当你用s初始化tt1和tt2时,self.v = vv并没有复制整个数组,只是让tt1.v、tt2.v和s这三个变量都指向内存中同一个数组对象。后续add方法里的aux[i] += h是直接修改这个共享数组的内容,所以所有指向它的变量都会看到变化。
  • 标量是不可变对象:像int、float这类不可变对象,当你执行+=这类操作时,其实是创建了一个新的对象,而不是修改原来的。比如用s=1初始化实例后,修改tt1.v会生成新的整数赋值给它,tt2.v还是指向原来的1,自然不会跟着变。

解决方案

如果想让每个实例拥有独立的数组,互不影响,只需要在初始化时复制数组即可,修改__init__方法:

def __init__(self,vv): 
    self.v = vv.copy()  # 创建数组副本

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 10:09:08