深入剖析python中函數的參數類型及引用


前面文章中,在定義爬蟲函數時重點研究了*args、**kwargs兩個參數的使用方法。

https://www.cnblogs.com/chen117/p/12952601.html

但在后面的學習中發現,當時對函數的理解還比較粗淺,經過更深入的學習——主要還是看了下面這篇知乎的狠貼,顛覆了之前了解的分類方式,所以專門寫這篇總結一下。

https://www.zhihu.com/question/57726430

(當前最新的python版本是 3.8.3)

函數參數的作用是傳遞數據給函數使用。

一、參數有兩種形式:形參、實參。

【實參】

調用函數時的參數,格式:

https://www.cnblogs.com/chen117/p/12952601.html

funcname(實參表)

 

 

實參表由左到右就是簡單的兩個部分:

funcname(位置實參, 關鍵字實參) 

 

 

注意:這兩種實參前后順序是嚴格的,兩個部分都可以缺省,但不能相互交錯。(這確定了位置匹配的唯一性)

“關鍵字實參”可以擺脫位置約束。兩種實際參數要共同覆蓋所有沒有默認值的形式參數。

例1:(關鍵字實參形式可以擺脫位置約束)

 

 

【形參】

定義函數時的參數。

# 函數定義,獨立成塊的代碼,圓括號內是形式參數

def funcname(形參表):
    函數體

 

 

形參從左到右可以分為五個部分:

def funcname(【限定位置形參】,普通形參】,特殊形參args,限定關鍵字形參】,特殊形參kwargs):

    pass

 

 

 

其中兩個特殊形參分別只能是0個或1個,其他形參可以是0個或多個。

盡管函數定義的形式如此豐富,但調用形式永遠是簡單的兩部分——位置實參+關鍵字實參,與有無默認值無關。

二、形參類型:

1、限定位置形參:

純位置形參。是為了限制開頭幾個參數只能按位置傳遞。(不能使用關鍵字實參形式)

Python從3.7開始,為某些內置函數定義了positional-only的形參。從Python 3.8開始,positional-only形參將可正式用於自定義函數中,它們必須放在形參表的最前面,並在后面使用斜杠/(獨占一個參數位)與普通形參分隔。

例2.1:(a,b,c為限定位置形參,不能按關鍵字傳遞)

2、普通形參:

按最簡形式定義出來的就是【普通形參】,它們是“位置、關鍵字兼容”的。

例2.2:( d為普通形參,可以按位置傳遞,也可以按關鍵字傳遞)

  

3、限定關鍵字形參(命名關鍵字參數)

keyword-only限制后面幾個參數只能按關鍵字傳遞,這往往是因為后面幾個形參名具有十分明顯的含義,顯式寫出有利於可讀性;或者后面幾個形參隨着版本更迭很可能發生變化,強制關鍵字形式有利於保證跨版本兼容性。

必須傳入參數名,可以有缺省值。

例3.1:(d為限定關鍵字參數,只能按關鍵字傳遞)

 

 

例3.2:(當限定關鍵字參數d有缺省值時,可以省略)

 

 

4、特殊形參:*args

是一種可變參數,也叫元組參數。可以是元組也可以是列表序列。這種形式表示接受任意多個實際參數將其放到一個元組tuple中。

它位於普通形參之后,又只能接受位置實參。

例4:(雖然叫元組參數,但不要傳入一個元組對象進去,需要 * 解封。)

 

 

5、特殊形參:**kwargs

也是一種可變參數,也叫關鍵字參數、字典參數,這種形式表示接受任意多個實際參數將其放到一個字典dict中。

關鍵字參數是一個由鍵值對組成的集合,允許通過變量名進行匹配,而不是位置。

例5:(雖然叫字典參數,但不能傳入一個完整的字典對象,需要**解封)

 

6、混合參數

*args接收多余的位置實參,**kwargs接收多余的關鍵字實參。

*args 和 **kwargs 並不是 python 中的參數關鍵字,而是一種慣用寫法。

例6.1:

 

例6.2:命名關鍵字參數不能與可變參數 *args 組合,可以與 **kwargs 組合。

 

四、特殊傳參方法:

1、序列解包:

當你有個序列對象,想將其中元素解放出來作為調用函數的位置實參時,給它加個前綴*即可。

例7:

2、字典解包:

當你有個字典對象,且其中的鍵都是合法的形參名時,想把其中的鍵值對解放出來作為調用函數的關鍵字參數,給它加個前綴**即可。

例8:

 

 

 

 

 五、參數傳遞基本法則:

將實際參數傳遞給形參的方式有兩種:

值傳遞:實參為不可變對象,傳遞給形參后,形參的值改變,實參值不變。

引用傳遞:實參為可變對象,傳遞給形參后,形參的值改變,實參值改變。(傳遞地址)

當函數被調用時,解釋器會查看傳入的變量(內存地址)指向的類型,如果是可變類型的值,就按照引用傳遞變量;如果是一個非可變類型的值,就按照值傳遞變量。

 

盡管函數定義的形式如此豐富,但調用形式永遠是簡單的兩部分——位置實參+關鍵字實參。注意這兩個前后順序是嚴格的,兩個部分都可以缺省。

與有無默認值無關,位置實參永遠按位置傳遞給*或*args之前對應的形參(即限定位置形參和普通形參),多余的位置實參傳入*args(如果有的話);

關鍵字實參則匹配剩下的普通形參和限定關鍵字形參(非限定位置形參),多余的關鍵字實參則傳入**kwargs(如果存在的話)。


免責聲明!

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



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