python-變量與參數傳遞


變量與參數傳遞

理解變量

拋棄變量是存儲數據的盒子這一錯誤觀念,

可以把python變量理解為附加在對象上的標注

來個栗子

a = [1, 2, 3]
b = a
a.append(4)
print(a, b) #[1, 2, 3, 4] [1, 2, 3, 4]
print(a is b)

 

說明:a和b引用同一個列表,而不是這個列表的副本,當為a添加一個元素時,a,b都發生改變並指向同一個列表,

很明顯用變量是存儲數據的盒子這一觀念無法解釋。

 

變量賦值

在python中,通常會說把某個變量分配給某個對象,絕不會說把某個對象分配給某個變量,因為對象在賦值之前就創建了。

a = 3

說明:對於python中的賦值語句,應該先讀右邊,對象在右邊創建或獲取,之后將左邊的變量綁定到對象上,

這就像往對象上貼上標注。

 

變量只不過是標注,你無法阻止往對象上貼多個標注,貼的多個標注就是別名。

 

每個變量都有標識、類型和值,對象一旦創建它的標識就不會變,標識可以理解為對象在內存中的地址。

 

id()函數返回對象內存地址的整數表示,id是唯一的數值標識,在對象的生命周期中不會改變

標識通常用is運算符檢查

==比較的是兩個對象中保存的數據,

is比較的是兩個對象的標識,is常用於變量與單例值之間的比較:

x is None:

x is not None:

 

變量分類

在python中,一切都是對象,變量存儲的是對象的引用。

對象可以分為可變對象和不可變對象,可變與不可變是針對對象內容本身而言的。

 

對象分類 概念 包括
可變對象 對象創建后對象的內容是可以改變的 list, dict, set
不可變對象 對象創建后對象的內容是不可以改變的 bool, int, float, tuple, str, frozens

 

 

栗子

不可變對象

x = 1
y = x
print(id(x), id(y), id(1)) #postion 1 (8791467483984 8791467483984 8791467483984)
x += 1
print(id(x), id(y), id(1)) #postion 2 (8791467484016 8791467483984 8791467483984)

 

x, y同時指向對象1,在position1位置,id(x), id(y), id(1)的內存地址一樣

x += 1, 開辟了新的內存空間,創建對象2,讓x重新指向新的對象2,但是原來的對象1和對象1的內存地址並沒有發生變化

優點:

減少重復對象對內存空間的占用

 

可變對象

可變對象的修改並不會開辟新的內存空間,而是直接在原內存空間上直接修改對象的內容

即對象的內存地址並不會改變,改變的是對象的內容

list1 = [1, 2]
print(list1, id(list1)) #position1 ([1, 2] 37249672)
list1.append(3)
print(list1, id(list1)) #position2 ([1, 2, 3] 37249672)

 

參數傳遞

python唯一支持的參數傳遞模式是共享傳參。

共享傳參指函數中的各個形參獲得對應實參中各個引用的副本,即函數內部的形參是實參的別名。

x = 1
y = [1, 2]
def fun(a, b):
    print(a is x, b is y)

fun(x, y) #True True

說明:當調用函數fun(x, y)時,a和x共同指向數字1,b和y共同指向列表[1, 2],即形參a是實參x的別名,形參b是實參y的別名。

 

注意:不要使用可變的對象作為參數的默認值,否則可能會得到意想不到的結果。

def extend_element(ele, eles=[]):
    eles.append(ele)
    return eles

list1 = extend_element('a')
list2 = extend_element(2, [1])
list3 = extend_element('b')
print(list1, '->', list2, '->', list3) #['a', 'b'] -> [1, 2] -> ['a', 'b']
print(list1 is list3) #True

說明:我們發現list1和list3指向同一個列表,這是為什么呢?

其實這個根源在於,默認值在定義函數時計算,通常在模塊加載時,因此默認值變成了函數對象的一個屬性。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM