Python支援混合使用不同的參數傳入方式,有指定位置、不指定、指定參數名稱。
def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):
----------- ---------- ----------
| | |
| Positional or keyword |
| - Keyword only
-- Positional only
在/
之前的參數指定位置傳入,/
到*
之間的參數不指定,*
之後的參數指定名稱傳入,默認是不指定。
不指定的情況
def f(x, y):
print('x = {}, y = {}'.format(x, y))
不指定的情況下,以下幾種方式都是可以使用的
f(10, 20)
f(x=10, y=20)
f(y=20, x=10)
都可以正常輸出
x = 10, y = 20
x = 10, y = 20
x = 10, y = 20
使用參數名稱傳入
在某些情況下我們會希望使用參數名稱傳入,尤其是參數型別相同、順序無慣例或者會誤用的情況,比如說姓名。
def name_no_specify(first, last):
print('Your first name is {}, last name is {}.'.format(first, last))
在不指定的情況下,以下使用方式都可以正常執行
name_no_specify('John', 'Neumann')
name_no_specify('錢', '學森')
由於姓名順序中英慣例不一樣,可能會造成誤用
Your first name is John, last name is Neumann.
Your first name is 錢, last name is 學森. # <- This is wrong
這時候我們可以強迫使用者指定參數名稱傳入
def name_specify(*, first, last):
print('Your first name is {}, last name is {}.'.format(first, last))
這時如果使用者不指定參數名稱傳入,會引發TypeError
name_specify('John', 'Neumann')
TypeError: name_specify() takes 0 positional arguments but 2 were given
只能使用以下方式傳入參數
name_specify(last='錢', first='學森')
name_specify(first='學森', last='錢')
輸出結果
Your first name is 學森, last name is 錢.
Your first name is 學森, last name is 錢.
結論
不需要指定的情況:
- 順序是有邏輯或慣例的,比如說直角坐標
f(x, y)
,大家已經很習慣(x, y)
這個順序,不指定就沒關係。 - 順序不影響結果,如
two_sum(num1, num2)
。
考慮指定位置或參數名稱的情況:
- 順序會影響結果,如
pow(base, exp)
。 - 順序沒有慣例或者容易有誤用情形,如姓名、地址等。
https://docs.python.org/3.9/tutorial/controlflow.html#special-parameters