Python的變量及其賦值
c/c++/c#/java 里面都有值傳遞,引用傳遞的概念,在Python中是如何的?
例
a = 1 b = a print(id(a),id(b)) #140723344823328 140723344823328
此時,變量a與變量b指向同一對象
變量的賦值,只是表示讓變量指向了某個對象,並不表示拷貝對象給變量;而一個對象,可以被多個變量所指向。

接着
a = a + 1 print(b) #1
由於整型變量(int),字符串(string)都是不可類型,a = a + 1 會創建一個值為2的新對象,並用a指向它。
因此,b指向的還是1這個對象。 【對於不可變對象(字符串,整型,元祖等等),所有指向該對象的變量的值總是一樣的,也不會改變。但是通過某些操作(+= 等等)更新不可變對象的值時,會返回一個新的對象。】

列表的例子
可變對象(列表,字典,集合等等)的改變,會影響所有指向該對象的變量。
l1 = [1, 2, 3] l2 = l1 l1.append(4) print(l1) #[1, 2, 3, 4] print(l2) #[1, 2, 3, 4]
由於l1是可變類型,因此l1.append(4)不會創建新對象,會在原列表中插入4,而l1與l2都是指向這個列表,所以值都為[1,2,3,4]
變量可以刪除,但對象無法被刪除。
l = [1, 2, 3] del l #l被刪除,對象[1,2,3]仍然存在
Python 函數的參數傳遞
1)
def my_func1(b): b = 2 a = 1 my_func1(a) print(a) #1
這里參數傳遞后 b與a 同時指向 值為1這個對象,接着b=2,系統建立2這個對象,並把b指向2,因此a還是指向值為1的對象
2) return讓 a 指向 b指向的 值為2的對象def my_func2(b): b = 2 return b a = 1 a = my_func2(a) print(a) #2
3)
def my_func3(l2): l2.append(4) l1 = [1, 2, 3] my_func3(l1) print(l1) #[1, 2, 3, 4]
l2與l1都指向[1,2,3]這個列表對象,列表是可變類型,列表對象的值修改后並不會重新創建一個新對象,指向這個對象的l1的值也相應變為[1,2,3,4]
4)
def my_func4(l2): l2 = l2 + [4] l1 = [1, 2, 3] my_func4(l1) print(l1)#[1, 2, 3]
l2=l2+[4] 會創建一個新的列表對象[1,2,3,4]並把l2指向這個新對象,因此l1不會受影響
5)
如果想把l1也指向新對象,則可以用return
def my_func5(l2): l2 = l2 + [4] return l2 l1 = [1, 2, 3] l1 = my_func5(l1) print(l1) #[1, 2, 3, 4]
第3)與第5的作用是一樣的,但實際中一般會使用return語句,語義會更加清晰
總結
- Python中參數的傳遞既不是值傳遞,也不是引用傳遞,而是賦值傳遞,或者是叫對象的引用傳遞,指向一個具體的對象
- 如果對象是可變的,當其改變時,所有指向這個對象的變量都會改變。
- 如果對象不可變,簡單的賦值只能改變其中一個變量的值,其余變量則不受影響。
參考
極客時間 《Python核心技術與實戰》專欄