本文為 Python Software Foundation -->Python 3.12.6 說明文件 -->Python教學文件 --> 4. 深入了解流程控制 -->4.8. 深入了解函式定義 繁體中文版導讀文章
續上篇
定義函式時使用的引數 (argument) 數量是可變的。總共有三種可以組合使用的形式。
為一個或多個引數指定預設值是很有用的方式。函式建立後,可以用比定義時更少的引數呼叫該函式。例如:
該函式可以用以下幾種方式被呼叫:
重要警告:預設值只求值一次。當預設值為可變物件,例如 list、dictionary(字典)或許多類別實例時,會產生不同的結果。例如,以下函式於後續呼叫時會累積曾經傳遞的引數:
如果不想在後續呼叫之間共用預設值,應以如下方式編寫函式:
函式也可以使用關鍵字引數,以 kwarg=value 的形式呼叫。舉例來說,以下函式:
接受一個必要引數 (voltage) 和三個選擇性引數 (state,action,和 type)。該函式可用下列任一方式呼叫:
但以下呼叫方式都無效:
函式呼叫時,關鍵字引數 (keyword argument) 必須在位置引數 (positional argument) 後面。所有傳遞的關鍵字引數都必須匹配一個可被函式接受的引數(actor 不是 parrot 函式的有效引數),而關鍵字引數的順序並不重要。此規則也包括必要引數,(parrot(voltage=1000) 也有效)。一個引數不可多次被賦值,下面就是一個因此限制而無效的例子:
當最後一個參數為 **name 形式時,它接收一個 dictionary(字典,詳見 Mapping Types --- dict),該字典包含所有可對應形式參數以外的關鍵字引數。**name 可以與 *name 參數(下一小節介紹)組合使用,*name 接收一個 tuple,該 tuple 包含一般參數以外的位置引數(*name 必須出現在 **name 前面)。例如,若我們定義這樣的函式:
它可以被如此呼叫且輸出結果如下:
注意,關鍵字引數的輸出順序與呼叫函式時被提供的順序必定一致。
在預設情況,引數能以位置或明確地以關鍵字傳遞给 Python 函式。為了程式的可讀性及效能,限制引數的傳遞方式是合理的,如此,開發者只需查看函式定義,即可確定各項目是按位置,按位置或關鍵字,還是按關鍵字傳遞。
函式定義可能如以下樣式:
/ 和 * 是選擇性的。這些符號若被使用,是表明引數被傳遞給函式的參數種類:僅限位置、位置或關鍵字、僅限關鍵字。關鍵字參數也稱為附名參數 (named parameters)。
若函式定義中未使用 / 和 * 時,引數可以按位置或關鍵字傳遞給函式。
此處再詳述一些細節,特定參數可以標記為僅限位置。若參數為僅限位置時,它們的順序很重要,且這些參數不能用關鍵字傳遞。僅限位置參數必須放在 /(斜線)之前。/ 用於在邏輯上分開僅限位置參數與其餘參數。如果函式定義中沒有 /,則表示沒有任何僅限位置參數。
/ 後面的參數可以是位置或關鍵字或僅限關鍵字參數。
要把參數標記為僅限關鍵字,表明參數必須以關鍵字引數傳遞,必須在引數列表中第一個僅限關鍵字參數前放上 *。
請看以下的函式定義範例,注意 / 和 * 記號:
第一個函式定義 standard_arg 是我們最熟悉的形式,對呼叫方式沒有任何限制,可以按位置或關鍵字傳遞引數:
第二個函式 pos_only_arg 的函式定義中有 /,因此僅限使用位置參數:
第三個函式 kwd_only_args 的函式定義透過 * 表明僅限關鍵字引數:
最後一個函式在同一個函式定義中,使用了全部三種呼叫方式:
最後,請看這個函式定義,如果 **kwds 內有 name 這個鍵,可能與位置引數 name 產生潛在衝突:
呼叫該函式不可能回傳 True,因為關鍵字 'name' 永遠是連結在第一個參數。例如:
使用 /(僅限位置引數)後,就可以了。函式定義會允許 name 當作位置引數,而 'name' 也可以當作關鍵字引數中的鍵:
換句話說,僅限位置參數的名稱可以在 **kwds 中使用,而不產生歧義。
此用例決定哪些參數可以用於函式定義:
說明:
如果不想讓使用者使用參數名稱,請使用僅限位置。當參數名稱沒有實際意義時,若你想控制引數在函式呼叫的排列順序,或同時使用位置參數和任意關鍵字時,這種方式很有用。
當參數名稱有意義,且明確的名稱可讓函式定義更易理解,或是你不希望使用者依賴引數被傳遞時的位置時,請使用僅限關鍵字。
對於應用程式介面 (API),使用僅限位置,以防止未來參數名稱被修改時造成 API 的中斷性變更。