Python 中的函數(shù)參數(shù)
在通常情況下,定義函數(shù)時(shí),函數(shù)的參數(shù)個(gè)數(shù)是預(yù)先確定的。例如,編寫計(jì)算兩個(gè)數(shù)相加的函數(shù) add(a, b),代碼如下:
def add(a, b):
return a + b
sum = add(1, 2)
- 在第 1 行,定義了函數(shù) add,函數(shù)有兩個(gè)參數(shù),第 1 個(gè)參數(shù)是 a,第 2 個(gè)參數(shù)是 b
- 在第 2 行,計(jì)算參數(shù) a 和 參數(shù) b 的累加和,通過(guò) return 語(yǔ)句將計(jì)算結(jié)果返回給調(diào)用者
- 在第 4 行,通過(guò) add(1, 2) 調(diào)用函數(shù) add
- 將整數(shù) 1 傳遞給第 1 個(gè)參數(shù) a
- 將整數(shù) 2 傳遞給第 2 個(gè)參數(shù) b
傳入的兩個(gè)整數(shù)按照位置順序依次賦給函數(shù)的參數(shù) a 和 b,參數(shù) a 和參數(shù) b 被稱為位置參數(shù)。
在 Python 中,調(diào)用函數(shù)時(shí),根據(jù)函數(shù)定義的參數(shù)位置來(lái)傳遞參數(shù),要求傳遞的參數(shù)與函數(shù)定義的參數(shù)兩者一一對(duì)應(yīng),如果 “傳遞的參數(shù)個(gè)數(shù)” 不等于 “函數(shù)定義的參數(shù)個(gè)數(shù)”,運(yùn)行時(shí)會(huì)報(bào)錯(cuò),例如:
def add(a, b):
return a + b
sum = add(1, 2, 3)
- 在第 1 行,定義了函數(shù) add,函數(shù)有 2 個(gè)參數(shù)
- 在第 4 行,通過(guò) add(1, 2, 3) 調(diào)用函數(shù) add,傳遞了 3 個(gè)參數(shù)
因?yàn)?“傳遞的參數(shù)個(gè)數(shù)” 不等于 “函數(shù)定義的參數(shù)個(gè)數(shù)”,運(yùn)行時(shí)報(bào)錯(cuò)如下:
C:\> python add.py
Traceback (most recent call last):
File "error.py", line 4, in <module>
sum = add(1, 2, 3)
TypeError: add() takes 2 positional arguments but 3 were given
在第 5 行,運(yùn)行時(shí)提示:函數(shù) add 有 2 個(gè)位置參數(shù),但是調(diào)用時(shí)傳遞了 3 個(gè)位置參數(shù)。
1. 位置參數(shù)實(shí)例
1.1 函數(shù)沒(méi)有任何位置參數(shù)
def hello_world():
print('hello')
print('world')
hello_world()
程序運(yùn)行輸出如下:
hello
world
1.2 函數(shù)有 1 個(gè)位置參數(shù)
def hello_world(n):
for i in range(n):
print('hello world')
hello_world(3)
程序運(yùn)行輸出如下:
hello world
hello world
hello world
1.3 函數(shù)有 2 個(gè)位置參數(shù)
def hello_world(n, string):
for i in range(n):
print(string)
hello_world(n, 'HELLO WORLD')
程序運(yùn)行輸出如下:
HELLO WORLD
HELLO WORLD
HELLO WORLD
2. 默認(rèn)參數(shù)
2.1 概述
調(diào)用函數(shù)時(shí),“傳遞的參數(shù)” 需要與 “函數(shù)定義的參數(shù)” 一一對(duì)應(yīng),例如:
def add_student(name, age, city):
print(name)
print(age)
print(city)
add_student('tom', 10, 'nanjing')
- 在第 1 行,定義函數(shù) add_student,函數(shù)定義了 3 個(gè)參數(shù)
- 在第 5 行,調(diào)用函數(shù) add_student,傳遞了 3 個(gè)參數(shù)
程序正常運(yùn)行,輸出結(jié)果如下:
tom
10
nanjing
如果 “傳遞的參數(shù)個(gè)數(shù)” 少于 “函數(shù)定義的參數(shù)個(gè)數(shù)”,程序會(huì)報(bào)錯(cuò),例如:
def add_student(name, age, city):
print(name)
print(age)
print(city)
add_student('jerry', 12)
- 在第 1 行,定義函數(shù) add_student,函數(shù)定義了 3 個(gè)參數(shù)
- 在第 5 行,調(diào)用函數(shù) add_student,傳遞了 2 個(gè)參數(shù)
程序運(yùn)行時(shí),報(bào)錯(cuò)如下:
Traceback (most recent call last):
File "add_student.py", line 5, in <module>
add_student('jerry', 12)
TypeError: enroll() missing 1 required positional argument: 'city'
在定義函數(shù)時(shí),可以為參數(shù)提供一個(gè)缺省值,如果傳遞參數(shù)時(shí),可以忽略部分參數(shù),舉例如下:
def add_student(name, age, city = 'nanjing'):
print(name)
print(age)
print(city)
add_student('jerry', 12)
- 在第 1 行,定義函數(shù) add_student,函數(shù)定義了 3 個(gè)參數(shù)
- 參數(shù) name 和參數(shù) age 是位置參數(shù)
- 參數(shù) city 是缺省參數(shù),該參數(shù)的缺省值是 'nanjing’
- 在第 5 行,調(diào)用函數(shù) add_student,傳遞了 2 個(gè)參數(shù)
- 參數(shù) name 被設(shè)定為 ‘jerry’
- 參數(shù) age 被設(shè)定為 12
- 調(diào)用函數(shù)時(shí)沒(méi)有傳遞參數(shù)給 city,因此參數(shù) city 被設(shè)定為缺省值 ‘nanjing’
程序正常運(yùn)行,輸出結(jié)果如下:
tom
10
nanjing
2.2 簡(jiǎn)化函數(shù)調(diào)用
現(xiàn)在需要多次調(diào)用 add_student 對(duì)一批學(xué)生進(jìn)行處理,可以使用如下代碼:
def add_student(name, age, city):
print(name)
print(age)
print(city)
add_student('tom', 10, 'nanjing')
add_student('jerry', 12, 'nanjing')
add_student('mike', 12, 'nanjing')
add_student('john', 11, 'nanjing')
add_student('jobs', 13, 'beijing')
- 在第 6 行到第 10 行,新增 5 個(gè)學(xué)生 tom、jerry、mike、john、jobs
- 大部分學(xué)生來(lái)自于相同的城市,極個(gè)別學(xué)生來(lái)自于外地城市
使用默認(rèn)參數(shù),可以簡(jiǎn)化函數(shù)的調(diào)用,尤其是在函數(shù)需要被頻繁調(diào)用的情況下。因?yàn)榇蟛糠謱W(xué)生來(lái)自于 nanjing,可以為參數(shù) city 設(shè)定一個(gè)默認(rèn)值 nanjing,如下所示:
def add_student(name, age, city="nanjing"):
print(name)
print(age)
print(city)
add_student('tom', 10)
add_student('jerry', 12)
add_student('mike', 12)
add_student('john', 11)
add_student('jobs', 13, 'beijing')
- 在第 6 行到第 10 行,新增 4 個(gè)學(xué)生 tom、jerry、mike、john,這 4 個(gè)學(xué)生來(lái)自于相同的城市 ‘nanjing’,調(diào)用函數(shù) add_student 時(shí)不需要的傳遞參數(shù) ‘nanjing’
- 在第 10 行,新增 1 個(gè)學(xué)生 jobs,該學(xué)生來(lái)自于 beijing,調(diào)用函數(shù) add_student 時(shí)需要的傳遞參數(shù) ‘beijing’
3. 可變參數(shù)
3.1 概述
假設(shè)需要編寫一個(gè)函數(shù) add,函數(shù) add 計(jì)算 2 個(gè)數(shù)的累加和,代碼如下:
def add(a, b):
return a + b
add(1, 2)
編寫計(jì)算 3 個(gè)數(shù)的累加和函數(shù),代碼如下:
def add3(a, b, c):
return a + b + c
add3(1, 2, 3)
如果需要編寫計(jì)算 4 個(gè)數(shù)的累加和函數(shù),可以用上述方式再增加一個(gè)函數(shù),顯然,這樣的方法是繁瑣的。我們的需求是:編寫一個(gè)計(jì)算累加和的函數(shù) add,但是函數(shù) add 的參數(shù)個(gè)數(shù)是預(yù)先不確定的。
Python 提供了一種可變參數(shù)機(jī)制用于解決這樣的問(wèn)題,在函數(shù)定義中,可以將函數(shù)設(shè)定為可以接受任意數(shù)量的參數(shù),函數(shù)調(diào)用時(shí)就可以傳遞任意數(shù)量的參數(shù)。
在函數(shù)定義中,在參數(shù)前加上符號(hào) * 表示函數(shù)可以接受可變數(shù)量的參數(shù),如下所示:
def 函數(shù)(*args):
函數(shù)體
- 該函數(shù)被設(shè)定為能夠接受可變數(shù)量的參數(shù)
- args 的類型是元組
- 調(diào)用該函數(shù)時(shí),所有的參數(shù)被合并成一個(gè)元組
- 合并后的元組被賦值給 args,通過(guò)遍歷 args 可以訪問(wèn)傳遞的參數(shù)
3.2 例子
使用可變參數(shù)重新實(shí)現(xiàn)計(jì)算累加和的函數(shù) add,函數(shù) add 能夠接受任意個(gè)數(shù)的參數(shù),代碼如下:
def add(*args):
sum = 0
for arg in args:
sum = sum + arg
print('len = %d, sum = %d' % (len(args), sum))
add(1)
add(1, 2)
add(1, 2, 3)
- 在第 1 行,定義函數(shù) add,args 是可變參數(shù),args 的類型是一個(gè)元組
- 在第 2 行,設(shè)定累加和 sum 的初值為 0
- 在第 3 行,調(diào)用函數(shù) add 時(shí),所有的參數(shù)被合并成一個(gè)元組賦值給 args,因此使用 for 循環(huán)遍歷元組 args,相當(dāng)于遍歷所有的輸入?yún)?shù)
- 在第 4 行,變量 arg 表示當(dāng)前遍歷的參數(shù),將其加入到變量 sum 中
- 在第 5 行,打印 args 的長(zhǎng)度和計(jì)算結(jié)果 sum
- 在第 7 行,傳遞 1 個(gè)參數(shù)給 add
- 在第 8 行,傳遞 2 個(gè)參數(shù)給 add
- 在第 9 行,傳遞 3 個(gè)參數(shù)給 add
程序運(yùn)行時(shí),輸出如下:
len = 1, sum = 1
len = 2, sum = 3
len = 3, sum = 6
4. 關(guān)鍵字參數(shù)
4.1 概述
通常情況下,調(diào)用函數(shù)時(shí),以直接給出參數(shù)值的形式傳遞參數(shù),如下所示:
def add(a, b):
return a + b
add(1, 2)
- 在第 3 行,整數(shù) 1 和整數(shù) 2 作為參數(shù)值傳遞給參數(shù) a 和 參數(shù) b
Python 允許調(diào)用函數(shù)時(shí),以 “參數(shù)名 = 參數(shù)值” 的形式傳遞參數(shù),如下所示:
def add(a, b):
return a + b
add(a = 1, b = 2)
"參數(shù)名 = 參數(shù)值" 形式的參數(shù),例如 a = 1 和 b = 2,被稱為關(guān)鍵字參數(shù)。在函數(shù)定義中,在參數(shù)前加上符號(hào) ** 參數(shù)表示函數(shù)可以接收關(guān)鍵字參數(shù),如下所示:
def 函數(shù)(**kw_args):
函數(shù)體
- 該函數(shù)被設(shè)定為能夠接收關(guān)鍵字參數(shù)
- kw_args 的類型是字典
- 調(diào)用該函數(shù)時(shí),所有的關(guān)鍵字參數(shù)被合并成一個(gè)字典
- 合并后的字典被賦值給 kw_args,通過(guò)訪問(wèn) kw_args 可以訪問(wèn)參數(shù)名和參數(shù)值
4.2 例子
假設(shè)需要通過(guò)兩種方式來(lái)創(chuàng)建一個(gè)人的姓名:
-
直接給出人的姓名,需要一個(gè)參數(shù):full_name
- 例子,如果 full_name 等于 ‘ZhangSan’,則用這種方式創(chuàng)建的姓名是 ‘ZhangSan’
-
分別給出人的姓和名,需要兩個(gè)參數(shù): first_name 和 last_name
- 參數(shù) first_name 表示姓
- 參數(shù) last_name 表示名
- 例子,如果 first_name 等于 ‘Zhang’、last_name 等于 ‘San’,則用這種方式創(chuàng)建的姓名是 ‘ZhangSan’
現(xiàn)在使用 Python 的關(guān)鍵字參數(shù)機(jī)制完成函數(shù) create_full_name,代碼如下:
def create_full_name(**kw_args):
if 'full_name' in kw_args:
full_name = kw_args['full_name']
return full_name
if 'first_name' in kw_args and 'last_name' in kw_args:
first_name = kw_args['first_name']
last_name = kw_args['last_name']
full_name = first_name + last_name
return full_name
print(create_full_name(full_name = 'ZhangSan'))
print(create_full_name(first_name = 'Li', last_name = 'Si'))
運(yùn)行程序,輸出結(jié)果如下:
ZhangSan
LiSi
- 在第 1 行,創(chuàng)建函數(shù) create_full_name,該函數(shù)能夠接受關(guān)鍵字參數(shù)
- 該函數(shù)被調(diào)用時(shí),所有關(guān)鍵字參數(shù)被合并成一個(gè)字典,被賦值給參數(shù) kw_args
- kw_args 的類型是字典,它包含了所有的關(guān)鍵字參數(shù)
- 在第 2 行,檢查 kw_args 中是否包含參數(shù) full_name
- 在第 3 行,從 kw_args 中獲取參數(shù) full_name 的值
- 在第 4 行,返回 full_name
- 在第 6 行,檢查 kw_args 中是否包含參數(shù) first_name 和 last_name
- 在第 7 行,從 kw_args 中獲取參數(shù) first_name 的值
- 在第 8 行,從 kw_args 中獲取參數(shù) last_name 的值
- 在第 9 行,根據(jù) first_name 和 last_name 計(jì)算 full_name
- 在第 10 行,返回 full_name
- 在第 13 行,通過(guò) “直接給出人的姓名” 的方式調(diào)用 create_full_name
- 傳遞關(guān)鍵字參數(shù) full_name = ‘ZhangSan’
- 關(guān)鍵字參數(shù)被合并入一個(gè)字典 kw_args
- 字典 kw_args 中包含一條鍵值對(duì)
- 在第 13 行,通過(guò) “分別給出人的姓和名” 的方式調(diào)用 create_full_name
- 傳遞關(guān)鍵字參數(shù) first_name = ‘Li’、last_name = ‘Si’
- 關(guān)鍵字參數(shù)被合并入一個(gè)字典 kw_args
- 字典 kw_args 中包含兩條鍵值對(duì)
5. 小結(jié)
這節(jié)課我們學(xué)習(xí)了函數(shù)的參數(shù),參數(shù)這個(gè)概念是函數(shù)使用中不可缺少的一環(huán)。在函數(shù)定義時(shí)的參數(shù)叫做"形參",而在函數(shù)調(diào)用時(shí)的參數(shù)叫做"實(shí)參"。一定要分清這兩個(gè)概念。