關於函式引數的基礎知識,請參閱函式概念。
參數名稱和變數名稱一樣,必須以字母或底線開頭,並且可以包含字母、底線或數字。 參數名稱不應包含空格或標點符號。
位置引數是依照參數綁定的順序傳入函式的值。 位置引數也可以選擇使用參數名稱來傳入:
def concat(greeting, name):
return f"{greeting}{name}"
# Passing data to the function by position.
print(concat("Hello, ", "Lilly"))
#-> Hello, Lilly
# Passing data to the function using the parameter name.
print(concat(name="Glenn", greeting="Hello, "))
#-> Hello, Glenn
第一次呼叫concat時,是依照位置傳入引數。
第二次呼叫concat時,則是使用名稱傳入引數,因此可以改變它們的位置。
請注意,位置引數不能接在使用名稱傳入的引數後面(也稱為關鍵字引數。不要和可變位置參數或 **kwargs 搞混)。
像這組引數:
print(concat(greeting="Hello, ", "Gregor"))
會產生這個錯誤:
SyntaxError: positional argument follows keyword argument
若要求呼叫函式時只能使用僅限位置引數,可以透過在參數清單中使用/運算子來達成:
# Parameters showing a position-only operator.
def concat(greeting, name, /):
return f"{greeting}{name}"
print(concat("Hello, ", "Ginnie"))
#-> Hello, Ginnie
# Call to the function using keyword arguments.
print(concat(name="Franklin", greeting="Hello, "))
Traceback (most recent call last):
print(concat(name="Franklin", greeting="Hello, "))
TypeError: concat() got some positional-only arguments passed as keyword arguments: 'greeting, name'
關鍵字引數是在呼叫函式時使用參數名稱。 它們也可以選擇依照位置來傳入:
def concat(greeting, name):
return f"{greeting}{name}"
# Function call using parameter names as argument keywords.
print(concat(name="Eliza", greeting="Hello, "))
#-> Hello, Eliza
# Function call with positional data as arguments.
print(concat("Hello, ", "Tim"))
#-> Hello, Tim
若要求呼叫函式時只能使用僅限關鍵字引數,可以透過在參數清單中使用*運算子來達成:
# Function definition requiring keyword-only arguments.
def concat(*, greeting, name):
return f"{greeting}{name}"
# Keyword arguments can be in an arbitrary order.
print(concat(name="Kimmie", greeting="Hello, "))
#-> Hello, Kimmie
# Calling the function with positional data raises an error.
print(concat("Hello, ", "Coleen"))
Traceback (most recent call last):
print(concat("Hello, ", "Coleen"))
TypeError: concat() takes 0 positional arguments but 2 were given
可以在參數清單中為一個或多個引數提供預設值。 這樣一來,需要時就能用_更少_的引數來呼叫函式。 只要在呼叫函式時傳入新的引數值,就能覆寫預設值:
# Function with default argument values.
def concat(greeting, name="you", punctuation="!"):
return f"{greeting}, {name}{punctuation}"
print(concat("Hello"))
#-> Hello, you!
# Overriding the default values
print(concat("Hello", name="Polly", punctuation="."))
#-> Hello, Polly.
如果參數定義中沒有使用/或*運算子,引數就既可以依照位置、也可以使用關鍵字傳入。
或者,也可以把位置或關鍵字引數放在左邊的僅限位置參數,以及右邊的僅限關鍵字參數之間:
# Position-only argument followed by position-or-keyword, followed by keyword-only.
def concat(greeting, /, name, *, ending):
return f"{greeting}{name}{ending}"
print(concat("Hello, ", "Mark", ending="!"))
#-> Hello, Mark!
print(concat("Hello, ", name="Rachel", ending="!"))
#-> Hello, Rachel!
print(concat(greeting="Hello, ", name="JoJo", ending="!"))
Traceback (most recent call last):
print(concat(greeting="Hello, ", name="JoJo", ending="!"))
TypeError: concat() got some positional-only arguments passed as keyword arguments: 'greeting'
*args程式碼範例經常會出現像下面這樣的函式定義:
def my_function(*args, **kwargs):
# code snipped
*args是由兩部分組成的名稱,代表內含不定數量個別位置引數的tuple,也稱為variadic argument。
args是賦予這組引數tuple的名稱,但也可以換成任何其他有效的 Python 名稱,例如my_args、arguments等。
*是用來把這群個別引數轉換成tuple的運算子。
由於tuple可以被疊代,args可以傳給任何接受可疊代物件的函式。
雖然*args經常和**kwargs一起出現,但並不是非得如此:
def add(*args):
# args is passed to the sum function, which iterates over it.
return sum(args)
print(add(1, 2, 3))
#-> 6
如果*args接在一個或多個位置引數後面,*args就會是位置引數之後剩下的部分:
def add(first, *args):
# first will be 1, leaving the values 2 and 3 in *args
return first + sum(args)
print(add(1, 2, 3))
#-> 6
如果在*args之後定義了一個或多個預設引數,它們會和*args的值分開:
def add(first, *args, last=0):
return first + sum(args) + last
print(add(1, 2, 3))
#-> 6
print(add(1, 2, 3, last=4))
#-> 10
# This uses the unpacking operator * to separate the list elements into positional arguments.
# It does not have the same behavior as the * (packing) in *args.
print(add(*[1, 2, 3]))
#-> 6
請注意,當引數本身已經放在iterable裡(例如tuple或list),在傳給接受任意數量個別引數的函式之前,必須先拆解。
這是透過*來完成的,也就是拆解運算子。
在這個情境下,*會把容器_拆解_成一個個元素,再由*args轉換成tuple。
如果只有位置引數,拆解的結果必須和已定義的正式參數數量相同。
如果不先拆解傳入add的 list,程式就會發生錯誤:
def add(first, *args, last=0):
return first + sum(args) + last
print(add([1, 2, 3]))
Traceback (most recent call last):
print(add([1, 2, 3]))
return first + sum(args) + last
TypeError: can only concatenate list (not "int") to list
**kwargs**kwargs是由兩部分組成的名稱,代表不定數量個別的鍵值對引數。
kwargs是這群引數的名稱,也可以換成其他名稱,例如my_args、arguments等。
**會把這群具名引數轉換成由{argument name: argument value}配對組成的dictionary。
由於字典可以被疊代,kwargs可以傳給任何接受可疊代物件的函式。
雖然**kwargs經常和*args一起出現,但並不是非得如此:
def add(**kwargs):
return sum(kwargs.values())
print(add(one=1, two=2, three=3))
#-> 6
請注意,這裡呼叫了dict.values()方法來逐一遍歷kwargs字典的values。
疊代字典時,預設是疊代_keys_,所以必須明確指定dict.values():
def concat(**kwargs):
# Join concatenates the tuples from `kwargs.items()`
return " ".join((str(item) for item in kwargs.items()))
print(concat(one=1, two=2, three=3))
#-> ('one', 1) ('two', 2) ('three', 3)