[TOC]
Python 函數(shù)參數(shù)
前言
最近在跟同事討論一個(gè)方法的調(diào)用時(shí)涉及到了 Python 函數(shù)的位置參數(shù)和關(guān)鍵字參數(shù)的相關(guān)知識(shí)璧针,發(fā)現(xiàn)之前學(xué)習(xí) Python 時(shí)對(duì)函數(shù)參數(shù)研究的并不透徹诫给,且很多地方已經(jīng)有些生疏了,故而查閱了一下 Python 官方文檔和廖雪峰的官網(wǎng)中的相關(guān)知識(shí)陋桂,并記錄總結(jié)如下。
Argument 和 Parameter
Python 函數(shù)參數(shù)根據(jù)使用情況的不同需要分為 Parameter 和 Argument 兩部分進(jìn)行討論。
Argument
Argument 指的是函數(shù)調(diào)用時(shí)的實(shí)際參數(shù)杨箭,即實(shí)參 (actual parameter),也可以稱為引數(shù)储狭。
Python 中有兩種 Argument互婿,分別是「位置參數(shù)」和「關(guān)鍵字參數(shù)」
位置參數(shù) [positional argument]
位置參數(shù)使用時(shí)可以放在參數(shù)列表的開(kāi)頭,和/或是以一個(gè)帶有 *
前綴的可迭代的元素表示辽狈,以內(nèi)置函數(shù) complex() 的調(diào)用為例:
complex(3, 5)
complex(*(3, 5))
==*
表示將可迭代對(duì)象擴(kuò)展為函數(shù)的參數(shù)列表==
關(guān)鍵字參數(shù) [keyword argument]
關(guān)鍵字參數(shù)使用時(shí)需要用標(biāo)識(shí)符指明(name=
的形式)慈参,或是以一個(gè)帶有 **
前綴的字典表示,以內(nèi)置函數(shù) complex() 的調(diào)用為例:
complex(real=3, imag=5)
complex(**{'real': 3, 'imag': 5})
==**
表示將字典擴(kuò)展為函數(shù)的關(guān)鍵字參數(shù)==
Parameter
Parameter 指的是函數(shù)定義時(shí)的形式參數(shù)刮萌,即形參 (formal parameter)驮配。Python 中有五種 Parameter,分別是「位置或關(guān)鍵字參數(shù)」着茸、「僅位置參數(shù)」壮锻、「僅關(guān)鍵字參數(shù)」、「可變位置參數(shù)」元扔、「可變關(guān)鍵字參數(shù)」
位置或關(guān)鍵字參數(shù) [positional-or-keyword]
位置或關(guān)鍵字參數(shù)在函數(shù)調(diào)用時(shí)可以以位置參數(shù) (positional argument) 或關(guān)鍵字參數(shù) (keyword argument) 的形式提供躯保。它是默認(rèn)的參數(shù)類型。
def func(foo1, foo2=None): ...
其中 foo1 也可稱為非默認(rèn)參數(shù) [non-default parameter]澎语;foo2 可稱為默認(rèn)參數(shù) [default parameter]途事,默認(rèn)參數(shù)帶有默認(rèn)值验懊,可以簡(jiǎn)化函數(shù)調(diào)用。
注意尸变,在函數(shù)定義時(shí)非默認(rèn)參數(shù)必須在默認(rèn)參數(shù)之前义图。
僅位置參數(shù) [positional-only]
僅位置參數(shù)在函數(shù)調(diào)用時(shí)只能由位置參數(shù) (positional argument) 提供。Python 沒(méi)有提供定義該參數(shù)的語(yǔ)法召烂,它只在一些內(nèi)置函數(shù)中存在碱工,例如 abs()
。
僅關(guān)鍵字參數(shù) [keyword-only]
僅關(guān)鍵字參數(shù)在函數(shù)調(diào)用時(shí)只能由關(guān)鍵字參數(shù) (keyword argument) 提供奏夫,它可以對(duì)函數(shù)傳入的關(guān)鍵字參數(shù)進(jìn)行限制怕篷。
僅關(guān)鍵字參數(shù)定義時(shí)需要在其之前緊鄰一個(gè)可變位置參數(shù)或增加一個(gè)特殊分割符 *
。
- 含有可變位置參數(shù)時(shí)以可變位置參數(shù)為分割酗昼,可變位置參數(shù)后都是僅關(guān)鍵字參數(shù)
def person(name, age, *args, city, job):
print(name, age, args, city, job)
可以這樣調(diào)用他
test_arg('beijin','wfp',age='25',job='hoker')
test_arg('beijin','wfp',addr='shanghai',age='25',job='hoker')
但是不能這樣調(diào)用他
test_arg('beijin','wfp','25',job='hoker')
會(huì)提示缺少一個(gè)參數(shù)廊谓,定義了命名關(guān)鍵字參數(shù)的話,必須要把全部的關(guān)鍵字參數(shù)傳入進(jìn)去
- 沒(méi)有可變位置參數(shù)時(shí)麻削,增加一個(gè)
*
作為特殊分隔符蒸痹,*
后面的都是僅關(guān)鍵字參數(shù)
def test_arg(city,name,*,age,job):
print(name, age, args, city, job)
==*
作為特殊分割符使用==
僅關(guān)鍵字參數(shù)可以設(shè)置默認(rèn)值,從而簡(jiǎn)化調(diào)用:
def person(name, age, *, city='Beijing', job):
print(name, age, city, job)
由于參數(shù) city 具有默認(rèn)值呛哟,調(diào)用時(shí)叠荠,可不傳入 city 參數(shù):
>>> person('Jack', 24, job='Engineer')
Jack 24 Beijing Engineer
使用命名關(guān)鍵字參數(shù)時(shí),要特別注意扫责,如果沒(méi)有可變參數(shù)榛鼎,就必須加一個(gè) 。如果缺少
*
Python 解釋器將無(wú)法識(shí)別 positional-or-keyword 和 keyword-only
可變位置參數(shù) [var-positional]
可變參數(shù)很簡(jiǎn)單公给,在 C/C++ 和 Java 等語(yǔ)言中都有借帘,就是用 *args
號(hào)來(lái)表示,例如
def test_arg(*arg): ...
==*
表示將函數(shù)調(diào)用時(shí)的多個(gè)參數(shù)打包成一個(gè)元組==
你可以傳入任意多個(gè)元素(包括0)到參數(shù)中淌铐,在函數(shù)調(diào)用時(shí)會(huì)自動(dòng)被認(rèn)為是一個(gè)元組
可變關(guān)鍵字參數(shù) [var-keyword]
可變關(guān)鍵字參數(shù)在 python 中習(xí)慣用 **kwargs
表示肺然,可以傳入0到任意多個(gè)“關(guān)鍵字-值”,參數(shù)在函數(shù)內(nèi)部被當(dāng)做一個(gè)字典
def test_arg(**kwargs): ...
def test_arg(city, **kwargs): ...
==**
表示將函數(shù)調(diào)用時(shí)的多個(gè)關(guān)鍵字參數(shù)打包成一個(gè)字典==
可以這樣調(diào)用它
test_arg(name='John', job='hoker')
test_arg('beijin', name='john')
關(guān)鍵字參數(shù)可以用來(lái)后期擴(kuò)充函數(shù)的功能腿准,例如:先設(shè)定必要的參數(shù)际起,之后選擇性的增加可選參數(shù)。
Parameter 組合使用時(shí)的順序
位置或關(guān)鍵字參數(shù)-非默認(rèn)參數(shù) > 位置或關(guān)鍵字參數(shù)-默認(rèn)參數(shù) > 可變位置參數(shù) > 僅關(guān)鍵字參數(shù) > 可變關(guān)鍵字參數(shù)
參考來(lái)源
https://docs.python.org/3.6/glossary.html#term-parameter
https://docs.python.org/3.6/glossary.html#term-argument
https://docs.python.org/3.6/faq/programming.html#faq-argument-vs-parameter
https://www.liaoxuefeng.com/wiki/1016959663602400/1017261630425888