Python中的函數(shù)參數(shù)傳遞問(wèn)題
一、前言
在調(diào)用函數(shù)時(shí),大多數(shù)情況下,主調(diào)函數(shù)和被調(diào)函用之間有數(shù)據(jù)傳遞關(guān)系,這就是有參數(shù)的函數(shù)形式。
函數(shù)參數(shù)的作用是傳遞數(shù)據(jù)給函數(shù)使用,函數(shù)利用接收的數(shù)據(jù)進(jìn)行具體的操作處理。
函數(shù)參數(shù)在定義函數(shù)時(shí)放在函數(shù)名稱后面的一對(duì)小括號(hào)中,如圖所示:

二、了解形式參數(shù)和實(shí)際參數(shù)
在使用函數(shù)時(shí),經(jīng)常會(huì)用到形式參數(shù)(形參)和實(shí)際參數(shù)(實(shí)參)。
兩者都叫做參數(shù)二者之間的區(qū)別先通過(guò)形式參數(shù)和實(shí)際參數(shù)的作用來(lái)進(jìn)行講解,再通過(guò)比喻進(jìn)行理解。
1.通過(guò)作用理解
形式傳參和實(shí)際參數(shù)在作用上的區(qū)別如下:
- 形式傳參:在定義函數(shù)時(shí),函數(shù)名后面括號(hào)中的參數(shù)為“形式參數(shù)”,也稱形參。
- 實(shí)際參數(shù):在調(diào)用一個(gè)函數(shù)時(shí),函數(shù)名后面括號(hào)中的參數(shù)為“實(shí)際參數(shù)”。也就是將函數(shù)的調(diào)用者提供給函數(shù)的參數(shù)稱為實(shí)際參數(shù),也稱為實(shí)參。

根據(jù)實(shí)參的類型不同,可以分為將實(shí)參的值傳遞個(gè)形參,和將實(shí)參的引用傳遞給形參兩種情況。
- 當(dāng)實(shí)參為不可變對(duì)象時(shí),進(jìn)行的是值傳遞
- 當(dāng)實(shí)參為可變對(duì)象時(shí),進(jìn)行的是引用傳遞
值傳遞和引用傳遞的基本區(qū)別:
- 進(jìn)行值傳遞后,改變形參的值,實(shí)參的值不變
- 進(jìn)行引用傳遞后,改變形參的值,實(shí)參的值也一同改變
實(shí)例:
# 定義函數(shù)
def demo(obj):
print("原值:", obj)
obj += obj
# 調(diào)用函數(shù)
print("==========值傳遞==========")
mot = "唯有在被追趕的時(shí)候,你才能真正地奔跑"
print("函數(shù)調(diào)用前:", mot)
demo(mot) # 采用不可變對(duì)象-字符串
print("函數(shù)調(diào)用后:", mot)
print("==========引用傳遞==========")
list1 = ["小白", "小名", "小紅"]
print("函數(shù)調(diào)用前:", list1)
demo(list1) # 采用可變對(duì)象-列表
print("函數(shù)調(diào)用后:", list1)
運(yùn)行結(jié)果如下:

2.通過(guò)比喻來(lái)理解形參和實(shí)參
函數(shù)定義時(shí)參數(shù)列表中的參數(shù)就是形參,而函數(shù)調(diào)用時(shí)傳遞進(jìn)來(lái)的參數(shù)就是實(shí)參,就像劇本選主角一樣,劇本的角色相對(duì)于形參,而演角色的演員就相對(duì)于實(shí)參。
三、位置參數(shù)
位置參數(shù)也稱必備參數(shù),必須按照正確的順序傳到函數(shù)中。即調(diào)用時(shí)的數(shù)量和位置必須和定義時(shí)是一樣的。
1.數(shù)量必須與定義時(shí)一致
在調(diào)用函數(shù)時(shí),指定的實(shí)參數(shù)量必須與形參一致,否則將拋出TypeError異常,提示缺少必要的位置參數(shù)。
例如:定義一個(gè)函數(shù)def fun_bmi(person, height, weight),該函數(shù)中有3個(gè)參數(shù),但調(diào)用時(shí)只傳兩個(gè)參數(shù),如下代碼所示:
def fun_bmi(person, height, weight):
"""
功能:根據(jù)身高和體重計(jì)算BMI指數(shù)
:param person: 姓名
:param height: 身高,單位:米
:param weight: 體重,單位:千克
"""
print(person + "的身高:" + str(height) + "米\t 體重:" + str(weight) + "千克")
bmi = weight / (height * height) # 用于計(jì)算BMI指數(shù),公式為“體重/身高的平方”
print(person + "的BMI指數(shù)為:" + str(bmi))
# 判斷身材是否合理
if bmi < 18.5:
print("您的體重過(guò)輕")
if 18.5 <= bmi < 24.9:
print("正常范圍,注意保持")
if 24.9 <= bmi < 29.9:
print("您的體重過(guò)重")
if bmi > 29.9:
print("肥胖")
fun_bmi("路人甲", 183)
運(yùn)行結(jié)果如下:

如上圖所示,拋出TypeError,具體意思是“fun_bmi()方法缺少一個(gè)必要的位置參數(shù)weight”。
2.位置必須與定義時(shí)一致
在調(diào)用函數(shù)時(shí),指定的實(shí)參位置與形參的位置一致,否則將產(chǎn)生一下兩個(gè)結(jié)果:
- 拋出TypeError異常產(chǎn)
- 生結(jié)果與預(yù)期不符的問(wèn)題
拋出異常的情況主要是因?yàn)樵谡{(diào)用函數(shù)時(shí),如果指定的實(shí)參與形參的位置不一致,但是他們的類型一致,那么就不會(huì)拋出異常,而是產(chǎn)生結(jié)果與預(yù)期不符的問(wèn)題。
例如,下列代碼:
def fun_bmi(person, height, weight):
"""
功能:根據(jù)身高和體重計(jì)算BMI指數(shù)
:param person: 姓名
:param height: 身高,單位:米
:param weight: 體重,單位:千克
"""
print(person + "的身高:" + str(height) + "米\t 體重:" + str(weight) + "千克")
bmi = weight / (height * height) # 用于計(jì)算BMI指數(shù),公式為“體重/身高的平方”
print(person + "的BMI指數(shù)為:" + str(bmi))
# 判斷身材是否合理
if bmi < 18.5:
print("您的體重過(guò)輕")
if 18.5 <= bmi < 24.9:
print("正常范圍,注意保持")
if 24.9 <= bmi < 29.9:
print("您的體重過(guò)重")
if bmi > 29.9:
print("肥胖")
fun_bmi("路人甲", 60, 183)
運(yùn)行結(jié)果如下:

函數(shù)調(diào)用后,沒(méi)有拋出異常,但是從結(jié)果看,產(chǎn)生結(jié)果與預(yù)期結(jié)果不一致。
四、關(guān)鍵字參數(shù)
關(guān)鍵字傳參是指使用形參的名字來(lái)確定輸入的參數(shù)。通過(guò)該方式指定實(shí)參時(shí),不需要與形參位置一致,只要參數(shù)名稱寫正確即可。
例如:調(diào)用def fun_bmi(person, height, weight)函數(shù),通過(guò)關(guān)鍵字傳參,代碼如下:
fun_bmi(height=1.83, weight=60, person="路人甲")
調(diào)用函數(shù),將顯示如下結(jié)果:

從上面結(jié)果可以看出,雖然指定實(shí)際傳參時(shí),順序與函數(shù)定義時(shí)不一致,但是運(yùn)行結(jié)果與預(yù)期結(jié)果是一致的。
五、為參數(shù)設(shè)置默認(rèn)值
調(diào)用函數(shù)時(shí),如果沒(méi)有指定某個(gè)參數(shù)將拋出異常,即在定義函數(shù)時(shí),直接指定形式參數(shù)的默認(rèn)值。
這樣,當(dāng)沒(méi)有傳入?yún)?shù)時(shí),則直接使用定義函數(shù)時(shí)設(shè)置的默認(rèn)值。
語(yǔ)法格式如下:
def functionname(...,[parameter1 = defaultvalue1]):[functionbody]
參數(shù)說(shuō)明:
functionname:函數(shù)名稱,在調(diào)用時(shí)使用parameter1 = defaultvalue1:可選參數(shù),用于指定向函數(shù)中傳遞的出納室,并且為該參數(shù)設(shè)置默認(rèn)值為defaultvalue1functionbody:可選參數(shù),用于指定函數(shù)體,即該函數(shù)被調(diào)用后,要執(zhí)行的功能代碼
注意:在定義函數(shù)時(shí),指定默認(rèn)的形參必須在所有參數(shù)的最后,否則將產(chǎn)生語(yǔ)法錯(cuò)誤。
使用可變對(duì)象作為函數(shù)參數(shù)的默認(rèn)值時(shí),多次調(diào)用可能會(huì)導(dǎo)致意料之外的情況,例如,編寫一個(gè)名稱為demo()的函數(shù),并為其設(shè)置一個(gè)帶默認(rèn)值的參數(shù),代碼如下:
def demo(obj=[]):
print("obj的值:", obj)
obj.append(1)
調(diào)用demo()函數(shù),代碼如下:
demo() # 調(diào)用函數(shù)
將顯示以下結(jié)果:

連續(xù)兩次調(diào)用,并不指定實(shí)際參數(shù),代碼如下:
demo() # 調(diào)用函數(shù) demo() # 調(diào)用函數(shù)
將顯示以下結(jié)果:

從上面結(jié)果看,這顯然不是我們想要的結(jié)果,為了防止出現(xiàn)這種情況,最好使用Nome作為可變對(duì)象的默認(rèn)值,這時(shí)還需要代碼檢查。修改后的代碼如下:
def demo(obj=None): # 定義一個(gè)函數(shù)
if obj == None: # 判斷是否為空
obj = []
print("obj的值:", obj) # 輸出obj值
obj.append(1) # 連續(xù)調(diào)用并輸出
這時(shí)在連續(xù)兩次調(diào)用函數(shù)demo()函數(shù),將顯示以下運(yùn)行結(jié)果:

六、可變參數(shù)
定義可變參,主要有兩個(gè)形式:
- *
parameter - **
parameter
1.*parameter
這種形式表示接收任意多個(gè)實(shí)際參數(shù)并將放到一個(gè)元組中。例如,定義一個(gè)函數(shù),讓其可以接收任意多個(gè)實(shí)際參數(shù),代碼如下:
def printplayer(*name): # 定義輸出我喜歡的NBA球員的函數(shù)
print("\n我喜歡的NBA球員有:")
for item in name:
print(item) # 輸出球員名稱
調(diào)用3次上面的函數(shù),分別指定不同個(gè)數(shù)的實(shí)際參數(shù),代碼如下:
printplayer("小紅")
printplayer("小紅", "小白")
printplayer("小紅", "小白", "小明")
執(zhí)行結(jié)果如下:

2.**parameter
這個(gè)形式表示接收任意多個(gè)顯式賦值的實(shí)際參數(shù),并將其放到一個(gè)字典中。例如,定義一個(gè)函數(shù),讓其可以接收任意多個(gè)顯式賦值的實(shí)際參數(shù),代碼如下:
def printsign(**sign): # 定義輸出姓名和綽號(hào)的函數(shù)
print() # 輸出一個(gè)空行
for key, value in sign.items(): # 遍歷字典
print("[" + key + "]的綽號(hào)是:" + value) # 輸出組合獲得信息
調(diào)用兩次printsign()函數(shù),代碼如下:
printsign(小紅="妖精", 小明="大聰明") printsign(小白="菜雞", 小李="不高興", 小張="沒(méi)頭腦")
執(zhí)行結(jié)果如下:

如果想要使用一個(gè)已經(jīng)存在的字典作為函數(shù)的可變參數(shù),可以在字典的名稱前加“**”。例如下面代碼:
dict1 = {"小白": "菜雞", "小李": "不高興", "小張": "沒(méi)頭腦"} # 定義一個(gè)字典
printsign(**dict1) # 通過(guò)字典指定函數(shù)的可變參
執(zhí)行結(jié)果如下:

總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Django3.0 異步通信初體驗(yàn)(小結(jié))
這篇文章主要介紹了Django3.0 異步通信初體驗(yàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12
Python Matplotlib庫(kù)安裝與基本作圖示例
這篇文章主要介紹了Python Matplotlib庫(kù)安裝與基本作圖,簡(jiǎn)單分析了Python使用pip命令安裝Matplotlib庫(kù)及繪制三角函數(shù)曲線的相關(guān)操作技巧,需要的朋友可以參考下2019-01-01
Python數(shù)據(jù)分析之Numpy庫(kù)的使用詳解
NumPy(Numerical Python)是Python的一種開源的數(shù)值計(jì)算擴(kuò)展。這種工具可用來(lái)存儲(chǔ)和處理大型矩陣,比Python自身的嵌套列表結(jié)構(gòu)要高效的多(該結(jié)構(gòu)也可以用來(lái)表示矩陣(matrix)),支持大量的維度數(shù)組與矩陣運(yùn)算,此外也針對(duì)數(shù)組運(yùn)算提供大量的數(shù)學(xué)函數(shù)庫(kù)2021-11-11
Python 通過(guò)正則表達(dá)式快速獲取電影的下載地址
這篇文章主要介紹了Python 通過(guò)正則表達(dá)式快速獲取電影的下載地址,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08
使用Python的Twisted框架編寫非阻塞程序的代碼示例
Twisted是基于異步模式的開發(fā)框架,因而利用Twisted進(jìn)行非阻塞編程自然也是必會(huì)的用法,下面我們就來(lái)一起看一下使用Python的Twisted框架編寫非阻塞程序的代碼示例:2016-05-05
詳解如何通過(guò)Python制作一個(gè)密碼生成器
定期更換密碼是一種非常重要的安全措施,這種做法可以有效地保護(hù)你的賬戶和個(gè)人信息不受黑客和網(wǎng)絡(luò)攻擊者的侵害。所以本文就來(lái)用Python制作一個(gè)密碼生成器吧2023-05-05
Python數(shù)學(xué)建模PuLP庫(kù)線性規(guī)劃實(shí)際案例編程詳解
本節(jié)以一個(gè)實(shí)際數(shù)學(xué)建模案例,來(lái)為大家講解PuLP求解線性規(guī)劃問(wèn)題的建模與編程。來(lái)鞏固加深大家對(duì)Python數(shù)學(xué)建模PuLP庫(kù)線性規(guī)劃的運(yùn)用理解2021-10-10
Python 實(shí)現(xiàn)兩個(gè)服務(wù)器之間文件的上傳方法
今天小編就為大家分享一篇Python 實(shí)現(xiàn)兩個(gè)服務(wù)器之間文件的上傳方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-02-02

