概念:
所有的變量都可以理解爲內存中的一個對象的“引用”。類型是屬於對象的,而不是變量。而對象有兩種,“可更改”與“不可更改”對象。在python中,strings,tuples和numbers是不可更改的對象,而list,dict,set等則屬於可以修改的對象。
下面來看下例子(numbers與list):
def foo(a):
print("foo_in:", a, id(a))
a += 1
print("foo_in:",a)
a = 1
foo(a)
print("foo_out:",a)
'''
輸出:
foo_in: 1 1723752672
foo_in: 2 1723752704
foo_out: 1 1723752672
'''
def foo(a):
a.append(2)
print("foo_in:",a,id(a))
a = [1]
foo(a)
print("foo_out:",a,id(a))
'''
輸出:
foo_in: [1, 2] 2240850668936
foo_out: [1, 2] 2240850668936
'''
可知,1、在在執行完a+=1之後,a引用中保存的值,即內存地址發生變化,由原來1對象所在的地址變爲了2 這個實體對象所在的內存地址2、第二個例子a引用的內存值就不會發生改變
當一個引用傳遞給函數的時候,函數會自動複製一個引用,這個函數引用跟原來的那個引用沒有關係,(A第一個例子中函數引用指向一個不可變對象,操作對象(也就是改變了指向的內存),當函數返回時跟原來的引用並沒有影響。(B第二個例子,函數內引用指向的是可變對象,對它的操作就和定位了指針地址一樣,在內存裏進行修改。
再說一個例子(元組與列表):
元組中的不可變值得是元素值不可變,但其元素可以爲列表,當元素爲列表時,對於這個不可變實際上是說這個元素引用的地址不可變,對列表的操作並不改變引用的地址。
append()沒有改變列表的地址所以允許操作,而+法改變了引用地址所以不允許。