在Python中,所有对象分为可变对象和不可变对象。
其中,数值、字符串和元组是不可变对象;列表和字典是可变对象。
当程序试图改变数值类型的数据时,程序会自动生成新的数据,而不是改变原来的数据。
def func(x):
x += 1
x = 1
func(x)
print(x)
# 输出结果:1
这是因为主程序中的x和函数中的x是不一样的,即它们的地址不一样。
但如果将参数换成一个列表:
def func(x):
x.append(3)
y = [1, 2]
func(y)
print(y)
# 输出结果:[1, 2, 3]
可以看到,参数y发生了变化,如果不想要这种情况发生,即赋值时不进行可变对象的引用,而是直接新建一个地址并将数据复制。
我们可以使用Python的copy库来完成:
copy.copy:仅复制父对象而不复制子对象
copy.deepcopy:复制父对象和子对象
s1 = [1, 2, [3, 4, 5]]
s2 = s1
s3 = copy.copy(s1) # 只复制父对象,不复制子对象
s4 = copy.deepcopy(s1) # 复制父对象和子对象
s1.append(7)
s1[2].append(8)
print(s1, "\n", s2, "\n", s3, "\n", s4)
# 输出结果:
[1, 2, [3, 4, 5, 8], 7]
[1, 2, [3, 4, 5, 8], 7]
[1, 2, [3, 4, 5, 8]]
[1, 2, [3, 4, 5]]