python3函式預設引數的坑

2021-10-23 04:22:42 字數 1700 閱讀 5688

在定義乙個函式時,有的時候會新增預設引數。如

def

fun(a =0)

:pass

但預設引數倘若不注意會跳進乙個較大的坑,如

## 設定個標籤 flag

deffun

(l =

):1)

return l

a = fun(

)b = fun(

)

問此時a, b的值是什麼。倘若認為此時的 l 為區域性變數,則很容易答出a = [1], b = [1],但是應該是a = [1, 1], b = [1, 1]這一特性在python的官方文件中有特別說明,位置為:入門教程/4.7.1預設引數值

文件的大意為:

預設引數在函式被定義的同時也被定義。

舉個例子更加好理解:

i =

5def

fun(num = i)

:print

(num)

i =6

fun(

)#*****run*****

5

對前面flag中的函式可以這樣改編

l =

deffun

(l = l):1

)return l

a = fun(

)b = fun(

)

在這裡將上面預設引數的值,也就是空列表具體賦給變數 l(小寫l)。

接下來是python幾個特性的融合:

首先預設引數在函式被定義的時候被定義,所以 l 在函式被定義的時候得到空列表的指標。

但是由於在python中可變物件的傳遞都是傳遞指標,所以在兩次函式呼叫後 l, l, a, b 四個變數指向的都是同乙個記憶體位址。也就是:

那麼無論是誰對這片記憶體空間進行操作,四個指向此記憶體空間的變數都會發生改變(關於可變物件的特性建議學習c語言的指標進行更加深刻的理解,在此之前可以當作知識點背誦)

如果檢視 l 的值可以發現 l 的值也和a, b一樣。

那麼回到 flag 裡的函式

def

fun(l =

):1)

return l

a = fun(

)b = fun(

)

道理是完全一樣的:

首先預設引數在函式被定義的時候定義,所以 python 在記憶體中建立了乙個空列表,並且讓 l 指向空列表

呼叫兩次函式後 l, a, b 指向的是同一片記憶體空間

不同的是因為並沒有在全域性變數中定義乙個變數(如 l)指向這片空間,所以在主函式中是無法直接訪問這片空間的。

備註:雖然說 l 也是指向這片記憶體空間的,但是因為 l 的作用域只在函式內部,所以在主函式中是沒辦法通過 l 訪問這片記憶體空間。但是可以在函式內部指向此記憶體空間。

python3 函式 必選引數與預設引數

位置引數須以正確的順序傳入函式。呼叫時的數量必須和宣告時的一樣。def power x,n s 1 while n 0 n n 1s s x return sprint pow 5,3 125 修改後的power x,n 函式有兩個引數 x和n,這兩個引數都是位置引數,呼叫函式時,傳入的兩個值按照位...

python3 函式引數

python函式引數包括五種型別 位置引數 預設引數 可變引數 關鍵字引數以及命名關鍵字引數。位置引數例如 def ex y y就是位置引數 例子 def ex y print y ex 2 預設引數 可以簡化函式的呼叫,設定預設引數時,要注意 一 必選引數在前,預設引數在後 二當函式有多個引數時,...

python3函式的引數

函式的定義能簡化 的邏輯,對於函式的呼叫者來說,只需要知道如何正確的傳遞引數,以及知道函式將返回什麼值就可以了,而函式內部的複雜邏輯被封裝起來,呼叫者不必了解。呼叫函式時,傳入實參的值按照位置順序以此賦給形參。def power x,n s 1 while n n n 1s s x return s...