在python中将,数据类型分为可变类型和不可变类型:

可变类型有:列表list,字典dict

不可变类型有:整形int、浮点型float、字符串string、元组tuple

当我们将一个数据作为形参传入函数时,如果在函数内修改形参,会发生一下情况:

  • 当数据为不可变类型时,会生成一个新的对象,然后形参的标签指向新的对象,而实参的没有变
  • 当数据为可变类型时,形参和实参都指向同一个对象,修改形参会直接在实参的基础上修改(即使是使用了copy()函数,在有些情况下依然会改变)

所以我们在写python函数时,传入字典要和传入数组一样注意,里面的值会在函数里进行修改,特别是在递归调用的时候,即便是使用copy()函数复制一样会修改,但depp_copy()函数可以解决这个问题。

值得注意的是,在函数中重新定义数据并不会改变实参的值,只有修改才会
举个例子:

def test_func(num):
    num = {'a':2,'b':2}

def test_func_2(num):
    num['a'] = 2

test_dict = {'a':1, 'b':2}
print('原字典:')
print(test_dict)
print('重新赋值字典后:')
test_func(test_dict)
print(test_dict)
print('修改字典后:')
test_func_2(test_dict)
print(test_dict)

结果:

python中可变序列有哪些 python的可变类型有哪些_不可变类


可以看到对于字典而言,对形参重新复制并没有修改实参的值,但是修改形参却会影响到实参。

同时,对于copy()函数而言,由于一个变量很有可能不是指向一个完整的对象,所以变量的子元素依然会存在引用的清空。
举例:

import copy
def test_func_3(num):
    new_num = num.copy()
    new_num['c'] = 3
    new_num['a']['b'] = 3

def test_func_4(num):
    new_num = copy.deepcopy(num)
    new_num['a']['b'] = 4

test_dict = {'a':{'b':1},'c':2}

print('原字典:')
print(test_dict)
print('copy()修改字典后:')
test_func_3(test_dict)
print(test_dict)
print(' deepcopy()修改字典后:')
test_func_4(test_dict)
print(test_dict)

结果:

python中可变序列有哪些 python的可变类型有哪些_python_02


可以看到使用copy()函数后,首先修改c的值没有成功,但是修改a中子字典b的值却成功了,说明使用copy()函数是复制了大的字典,而对于字字典没有复制

但deepcopy()函数解决了这个问题,完整地复制了整个字典,没有再修改实参。