学习 Python 中,对 Python 中的参数传递存有疑惑,想知道传递的是一份拷贝还是引用地址,于是测试一番。
个人理解,如有误请指出。
测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
| print("==========列表==========") def listChanged(a): a[0] = 2 print(id(a))
a = [1] print("调用函数前:" + str(a)) listChanged(a) print(id(a)) print("调用函数后:" + str(a))
print("==========集合==========") def setChanged(a): a.add(2) print(id(a))
a = {1} print("调用函数前:" + str(a)) setChanged(a) print(id(a)) print("调用函数后:" + str(a))
print("==========字典==========") def dictChanged(a): a[1] = "2" print(id(a))
a = {1:"1"} print("调用函数前:" + str(a)) dictChanged(a) print(id(a)) print("调用函数后:" + str(a))
print("==========数值==========") def numberChanged(a): print("调用函数时:", id(a)) a += 1 print("重新赋值:", id(a))
a = 1 print("调用函数前:" + str(a)) numberChanged(a) print(id(a)) print("调用函数后:" + str(a))
print("==========字符串==========") def stringChanged(a): print("调用函数时:", id(a)) a += "a[:]" print("重新赋值:", id(a))
a = "1" print("调用函数前:" + str(a)) stringChanged(a) print(id(a)) print("调用函数后:" + str(a))
print("==========元组==========") def tupleChanged(a): print("调用函数时:", id(a)) a += ("合并两元组",) print("重新赋值:", id(a))
a = ("1", "2") print("调用函数前:" + str(a)) tupleChanged(a) print(id(a)) print("调用函数后:" + str(a))
print("==========带可变子元素的元组==========") def tuple2Changed(a): a[1][0] = "22" print(id(a))
a = ("1", ["2"]) print("调用函数前:" + str(a)) tuple2Changed(a) print(id(a)) print("调用函数后:" + str(a))
|
得到:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| ==========列表========== 调用函数前:[1] 2268560182080 2268560182080 调用函数后:[2] ==========集合========== 调用函数前:{1} 2268560447296 2268560447296 调用函数后:{1, 2} ==========字典========== 调用函数前:{1: '1'} 2268560123776 2268560123776 调用函数后:{1: '2'} ==========数值========== 调用函数前:1 调用函数时: 2268558420272 重新赋值: 2268558420304 2268558420272 调用函数后:1 ==========字符串========== 调用函数前:1 调用函数时: 2268560076912 重新赋值: 2268560559408 2268560076912 调用函数后:1 ==========元组========== 调用函数前:('1', '2') 调用函数时: 2268560166464 重新赋值: 2268560558592 2268560166464 调用函数后:('1', '2') ==========带可变子元素的元组========== 调用函数前:('1', ['2']) 2268560559232 2268560559232 调用函数后:('1', ['22'])
|
总结
作为参数传递进去时,都是传递的内存地址。
但是由于不可变类型无法改变,如果对它进行修改,即都是创建一个新对象,在内存中开辟一个新空间,且在函数内的此次修改并不影响外部的原有变量。
可变类型的传递,因为未新建对象,函数内外一直都是操作同一个对象。
不可变类型的元组内部包含【可变类型的子元素】,它对可变元素的修改仍是遵从可变类型的逻辑的。即修改它的可变子对象,不会重新创建,那么这个元组还是没有发生改变的(指它的内存地址和储存的元素内存地址没有变化,还是那个未变的元组对象,但是内容会被修改)。
不可变数据:Number(数字)、String(字符串)、Tuple(元组);
可变数据:List(列表)、Dictionary(字典)、Set(集合)。