函數的參數

定義函數時()里的參數叫做形參(形式參數),它只是一個變量名,接受調用時傳遞的實參,僅供函數體中的代碼調用。

函數調用時,傳入()里的參數叫實參(實際參數),它是實際的數據,會傳遞給形參。

形參

根據形參的功能和定義方式可以分為:

  • 必須參數
  • 默認參數
  • 動態參數
    • 位置動態參數
    • 關鍵字動態參數

必須參數

在定義函數時,如果要求調用者必須傳遞實參給這個形參,那麼這個形參就要定義為必須形參。

直接定義在函數名後的()里的形參就是必須形參。

例如上一節中的my_print函數中的contentcount。我們再來看一個案例:

定義一個函數,接收兩個數,然後打印它們的和

>>> def add(x,y):
...     print(x+y)
>>> add(1)		# 調用時必須傳遞實參給必須參數,否則報錯
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: add() missing 1 required positional argument: 'y'
>>> add(1,2)
3

默認參數

在定義函數時,某些形參有默認值,在調用時可以不接收實參,這種情況就可以定義為默認形參。

在函數名後()中,以參數名=默認值的形式定義的形參就是必須參數。

注意:默認參數必須定義在必須參數的後面

案例:

定義一個函數,它接收兩個參數contentcount

content是函數要打印的內容

count是函數打印的次數,如果不傳遞count默認打印1

>>> def my_print(content, count=1):
...     for i in range(count):
...        print(content)
# 調用
>>> my_print('好好學習,天天向上!')
'好好學習,天天向上!'
>>> my_print('好好學習,天天向上!', 2)
'好好學習,天天向上!'
'好好學習,天天向上!'

調用函數時傳遞實參給默認形參會覆蓋默認值。

動態參數

在定義函數時,不確定在調用時會傳遞多少個實參,可以定義為動態形參。

動態形參根據實參的傳遞方式又分為兩種。

位置動態參數

在函數名後的()中,在形參前加*號,這個形參就被定義為位置動態參數,通常位置動態參數的參數名為args

它用來接收函數調用時,以位置形式傳遞過來的超過形參數量的多餘的實參。

注意:位置動態參數必須定義在默認參數後面。

位置動態參數會將所有多餘的位置實參創建成一個元組。

>>> def func(a, *args):
...     print(args, type(args))
>>> func(1,2,3,4)
(2, 3, 4) <class 'tuple'>

案例:

定義一個函數,接受2個以上的數,打印它們的和。

>>> def add(x, y, *args):
...     sum = x + y
...     for i in args:
...         sum += i
...     print(sum)
>>> add(1, 2, 3, 4)
10

關鍵字動態參數

在函數名後的()中,在形參前加**號,這個形參就被定義為關鍵字動態參數,通常關鍵字動態參數的參數名為kwargs

它用來接收函數調用時,以關鍵字形式傳遞過來的超過形參數量的多餘的實參。

注意:關鍵字動態參數必須定義在位置動態參數的後面。

關鍵字動態參數會將多餘的關鍵字實參創建成一個字典

>>> def func(a, **kwargs):
...     print(kwargs, type(kwargs))
>>> func(a=1,b=2,c=3,d=4)
{'b': 2, 'c': 3, 'd': 4} <class 'dict'>

實參

調用函數時傳遞實參有兩種方式:

  • 位置傳遞
  • 關鍵字傳遞

位置傳遞

調用函數時,在小括號中以(實參1,實參2,...)的形式傳遞的實參會按照位置與形參一一對應,以這種方式傳遞的實參叫做位置實參。

案例:

定義一個函數實現打印一個數的n次冪。

>>> def my_power(x, n):
...     print(x**n)
>>> my_power(3,2)		# 3傳遞給x,2傳遞給n
9
>>> my_power(2,3)		# 2傳遞給x,3傳遞給n
8

關鍵字傳遞

調用函數時,在小括號中以(形參1=實參1,形參2=實參2,...)的形式,顯式的指定形參與實參的對應關係,以這種方式傳遞的實參叫做關鍵字實參。

注意:關鍵字實參必須寫在位置實參的後面。

案例:

使用關鍵字的方式調用my_power函數

>>> my_power(x=3,n=2)
9
>>> my_power(n=2,x=3)
9
>>> my_power(3,n=2)
9

參數解包

當一個函數接收多個參數時,如果參數存儲在一個列表或一個字典中時,調用起來非常不方便。看下面的案例:

>>> def func(a, *args):
...     print(args, type(args))
>>> ls = [1,2,3,4,5,6]
>>> fun(ls[0],ls[1],ls[2],ls[3],ls[4],ls[5])
1 2 (3, 4, 5, 6)
>>> def func(a, **kwargs):
...     print(kwargs, type(kwargs))
>>> dc =  {'a': 1, 'b': 2, 'c': 3, 'd': 4}
>>> fun(a=dc['a'], b=dc['b'], c=dc['c'], d=dc['d'])
1 2 {'c': 3, 'd': 4}

可以看到上面的案例調用時的不便,參數解包就是為了解決這些問題的。

*解包

在傳遞實參時,可以通過*對可迭代對象進行解包。

>>> func(ls[0],ls[1],ls[2],ls[3],ls[4],ls[5])
1 2 (3, 4, 5, 6)
>>> func(*ls)			# 與上面的寫法等價
1 2 (3, 4, 5, 6)

**解包

在傳遞實參時,可以通過**對字典進行解包。

>>> fun(a=dc['a'], b=dc['b'], c=dc['c'], d=dc['d'])
1 2 {'c': 3, 'd': 4}
>>> fun(**dc)			# 與上面的寫法等價
1 2 {'c': 3, 'd': 4}