python中有哪些赋值_python中的赋值,什么时候是传值什么时候是传址?
參數的傳遞是通過自動將對象賦值給本地變量名來實現的。在函數運行時,函數頭部的參數名是一個新的、本地的變量名,這個變量名是在函數的本地作用域內存在。參數的傳遞本質上就是python賦值的另一個實例而已。
那么,這個問題分為可變對象和不可變對象兩種情況進行討論:
在原處改變函數的可變對象參數的值會對調用者有影響。函數能夠就地改變傳入的可變對象,因此其結果會影響調用者,這其實和前面介紹過的對象賦值原理是一樣的;
而不可變對象的引用重新賦值會指向新的對象,因此不會改變調用者。
先看一個不可變對象的例子
def f(a):
a = 99
print(a)
b = 88
f(b)
print(b)
99
88
在函數中修改a對于調用函數的地方沒有任何影響,因為他在函數內部直接把本地變量a重置為了一個完全不同的新對象,所以他不會影響最初的變量b
而當參數傳遞像列表和字典這樣的可修改對象的時候,我們還需要注意,對這樣的可變對象的原處修改可能在函數退出后依然有效,并由此影響到調用者。
def change(a,b):
a = 2
b[0] = 'spam'
x = 1
l = [1,2]
change(x,l)
print(x,l)
1 ['spam', 2]
再次對比可以看出,調用者的不可變變量x沒有受到影響,而可變變量L在函數內部進行本地修改,并影響到了自身
可以看出,對于參數a,僅僅把本地變量a修改為引用一個完全不同的對象,并沒有改變調用者作用域中的名稱x的綁定。而參數b被傳給了一個可變對象(在調用者作用域中叫做L的列表),因為第二個賦值是一個在原處發生的對象改變,對函數中b[0]進行賦值的結果會在函數返回后影響L的值,他修改了b所引用的對象的一部分,因為引用共享對象的緣故,L也被同時改變。
再強調一次,其實參數傳遞后的本地修改過程和簡單對象賦值后的對象修改,實質上是一回事,換句話說就等于下面這個例子所描述的程序過程
L = [1,2]
b = L
b[0] = 'spam'
print(L)
['spam', 2]
那如何避免對可變參數的修改呢?
實際上,可變參數的原處修改行為并不是一個bug,它只是參數傳遞在python中工作的方式。在python中,默認通過引用進行函數的參數傳遞,是因為這通常是我們所想要的:這意味著不需要創建多個拷貝就可以在我們的程序中傳遞很大的對象。如果不想要函數內部在原處的修改影響傳遞給它的對象,那么,我們可以簡單的創建一個明確的可變對象的拷貝
def change(a,b):
a = 2
b[0] = 'spam'
x = 1
l = [1,2]
change(x,l[:])
print(x,l)
1 [1, 2]
或者在函數內部進行拷貝,這樣可以不改變傳入的對象,函數調用看上去沒有變化
def change(a,b):
b = b[:]
a = 2
b[0] = 'spam'
x = 1
l = [1,2]
change(x,l)
print(x,l)
1 [1, 2]
更系統、更深入的探討,可點擊進入我們的專欄《python數據科學之路》。醬油哥:來吧,一起踏上Python數據科學之路?zhuanlan.zhihu.com
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的python中有哪些赋值_python中的赋值,什么时候是传值什么时候是传址?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 调用支付jsapl缺少参数:totalf
- 下一篇: java并发核心知识体系精讲_JVM核心