20 Python 中的函式引數
在通常情況下,定義函式時,函式的引數個數是預先確定的。例如,編寫計算兩個數相加的函式 add(a, b),程式碼如下:
def add(a, b):
return a + b
sum = add(1, 2)
- 在第 1 行,定義了函式 add,函式有兩個引數,第 1 個引數是 a,第 2 個引數是 b
- 在第 2 行,計算引數 a 和 引數 b 的累加和,通過 return 語句將計算結果返回給呼叫者
- 在第 4 行,通過 add(1, 2) 呼叫函式 add
- 將整數 1 傳遞給第 1 個引數 a
- 將整數 2 傳遞給第 2 個引數 b
傳入的兩個整數按照位置順序依次賦給函式的引數 a 和 b,引數 a 和引數 b 被稱為位置引數
在 Python 中,呼叫函式時,根據函式定義的引數位置來傳遞引數,要求傳遞的引數與函式定義的引數兩者一一對應,如果 “傳遞的引數個數” 不等於 “函式定義的引數個數”,執行時會報錯,例如:
def add(a, b):
return a + b
sum = add(1, 2, 3)
- 在第 1 行,定義了函式 add,函式有 2 個引數
- 在第 4 行,通過 add(1, 2, 3) 呼叫函式 add,傳遞了 3 個引數
因為 “傳遞的引數個數” 不等於 “函式定義的引數個數”,執行時報錯如下:
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 行,執行時提示:函式 add 有 2 個位置引數,但是呼叫時傳遞了 3 個位置引數。
1. 位置引數例項
1.1 函式沒有任何位置引數
案例演示 預覽 複製 複製成功!def hello_world ():
print('hello')
print('world')
hello_world()
執行案例 點選 "執行案例" 可檢視線上執行效果 程式執行輸出如下:
hello
world
1.2 函式有 1 個位置引數
案例演示 預覽 複製 複製成功!def hello_world(n):
for i in range(n):
print('hello world')
hello_world(3)
執行案例 點選 "執行案例" 可檢視線上執行效果 程式執行輸出如下:
hello world
hello world
hello world
1.3 函式有 2 個位置引數
案例演示 預覽 複製 複製成功!def hello_world(n, string):
for i in range(n):
print(string)
hello_world(n, 'HELLO WORLD')
執行案例 點選 "執行案例" 可檢視線上執行效果 程式執行輸出如下:
HELLO WORLD
HELLO WORLD
HELLO WORLD
2. 預設引數
2.1 概述
呼叫函式時,“傳遞的引數” 需要與 “函式定義的引數” 一一對應,例如:
案例演示 預覽 複製 複製成功!def add_student(name, age, city):
print(name)
print(age)
print(city)
add_student('tom', 10, 'nanjing')
執行案例 點選 "執行案例" 可檢視線上執行效果 - 在第 1 行,定義函式 add_student,函式定義了 3 個引數
- 在第 5 行,呼叫函式 add_student,傳遞了 3 個引數
程式正常執行,輸出結果如下:
tom
10
nanjing
如果 “傳遞的引數個數” 少於 “函式定義的引數個數”,程式會報錯,例如:
案例演示 預覽 複製 複製成功!def add_student(name, age, city):
print(name)
print(age)
print(city)
add_student('jerry', 12)
執行案例 點選 "執行案例" 可檢視線上執行效果 - 在第 1 行,定義函式 add_student,函式定義了 3 個引數
- 在第 5 行,呼叫函式 add_student,傳遞了 2 個引數
程式執行時,報錯如下:
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'
在定義函式時,可以為引數提供一個預設值,如果傳遞引數時,可以忽略部分引數,舉例如下:
案例演示 預覽 複製 複製成功!def add_student(name, age, city = 'nanjing'):
print(name)
print(age)
print(city)
add_student('jerry', 12)
執行案例 點選 "執行案例" 可檢視線上執行效果 - 在第 1 行,定義函式 add_student,函式定義了 3 個引數
- 引數 name 和引數 age 是位置引數
- 引數 city 是預設引數,該引數的預設值是 'nanjing’
- 在第 5 行,呼叫函式 add_student,傳遞了 2 個引數
- 引數 name 被設定為 ‘jerry’
- 引數 age 被設定為 12
- 呼叫函式時沒有傳遞引數給 city,因此引數 city 被設定為預設值 ‘nanjing’
程式正常執行,輸出結果如下:
tom
10
nanjing
2.2 簡化函式呼叫
現在需要多次呼叫 add_student 對一批學生進行處理,可以使用如下程式碼:
案例演示 預覽 複製 複製成功!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 個學生 tom、jerry、mike、john、jobs
- 大部分學生來自於相同的城市,極個別學生來自於外地城市
使用預設引數,可以簡化函式的呼叫,尤其是在函式需要被頻繁呼叫的情況下。因為大部分學生來自於 nanjing,可以為引數 city 設定一個預設值 nanjing,如下所示:
案例演示 預覽 複製 複製成功!def add_student(name, age, city):
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 個學生 tom、jerry、mike、john,這 4 個學生來自於相同的城市 ‘nanjing’,呼叫函式 add_student 時不需要的傳遞引數 ‘nanjing’
- 在第 10 行,新增 1 個學生 jobs,該學生來自於 beijing,呼叫函式 add_student 時需要的傳遞引數 ‘beijing’
3. 可變引數
3.1 概述
假設需要編寫一個函式 add,函式 add 計算 2 個數的累加和,程式碼如下:
案例演示 預覽 複製 複製成功!def add(a, b):
return a + b
add(1, 2)
執行案例 點選 "執行案例" 可檢視線上執行效果 編寫計算 3 個數的累加和函式,程式碼如下:
案例演示 預覽 複製 複製成功!def add3(a, b, c):
return a + b + c
add3(1, 2, 3)
執行案例 點選 "執行案例" 可檢視線上執行效果 如果需要編寫計算 4 個數的累加和函式,可以用上述方式再增加一個函式,顯然,這樣的方法是繁瑣的。我們的需求是:編寫一個計算累加和的函式 add,但是函式 add 的引數個數是預先不確定的。
Python 提供了一種可變引數機制用於解決這樣的問題,在函式定義中,可以將函式設定為可以接受任意數量的引數,函式呼叫時就可以傳遞任意數量的引數。
在函式定義中,在引數前加上符號 * 表示函式可以接受可變數量的引數,如下所示:
def 函式(*args):
函式體
- 該函式被設定為能夠接受可變數量的引數
- args 的型別是元組
- 呼叫該函式時,所有的引數被合併成一個元組
- 合併後的元組被賦值給 args,通過遍歷 args 可以訪問傳遞的引數
3.2 例子
使用可變引數重新實現計算累加和的函式 add,函式 add 能夠接受任意個數的引數,程式碼如下:
案例演示 預覽 複製 複製成功!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 行,定義函式 add,args 是可變引數,args 的型別是一個元組
- 在第 2 行,設定累加和 sum 的初值為 0
- 在第 3 行,呼叫函式 add 時,所有的引數被合併成一個元組賦值給 args,因此使用 for 迴圈遍歷元組 args,相當於遍歷所有的輸入引數
- 在第 4 行,變數 arg 表示當前遍歷的引數,將其加入到變數 sum 中
- 在第 5 行,列印 args 的長度和計算結果 sum
- 在第 7 行,傳遞 1 個引數給 add
- 在第 8 行,傳遞 2 個引數給 add
- 在第 9 行,傳遞 3 個引數給 add
程式執行時,輸出如下:
len = 1, sum = 1
len = 2, sum = 3
len = 3, sum = 6
4. 關鍵字引數
4.1 概述
通常情況下,呼叫函式時,以直接給出引數值的形式傳遞引數,如下所示:
def add(a, b):
return a + b
add(1, 2)
- 在第 3 行,整數 1 和整數 2 作為引數值傳遞給引數 a 和 引數 b
Python 允許呼叫函式時,以 “引數名 = 引數值” 的形式傳遞引數,如下所示:
def add(a, b):
return a + b
add(a = 1, b = 2)
"引數名 = 引數值" 形式的引數,例如 a = 1 和 b = 2,被稱為關鍵字引數。在函式定義中,在引數前加上符號 ** 引數表示函式可以接收關鍵字引數,如下所示:
def 函式(**kw_args):
函式體
- 該函式被設定為能夠接收關鍵字引數
- kw_args 的型別是字典
- 呼叫該函式時,所有的關鍵字引數被合併成一個字典
- 合併後的字典被賦值給 kw_args,通過訪問 kw_args 可以訪問引數名和引數值
4.2 例子
假設需要通過兩種方式來建立一個人的姓名:
-
直接給出人的姓名,需要一個引數:full_name
- 例子,如果 full_name 等於 ‘ZhangSan’,則用這種方式建立的姓名是 ‘ZhangSan’
-
分別給出人的姓和名,需要兩個引數: first_name 和 last_name
- 引數 first_name 表示姓
- 引數 last_name 表示名
- 例子,如果 first_name 等於 ‘Zhang’、last_name 等於 ‘San’,則用這種方式建立的姓名是 ‘ZhangSan’
現在使用 Python 的關鍵字引數機制完成函式 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 and 'last_name' in kw:
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'))
執行案例 點選 "執行案例" 可檢視線上執行效果 執行程式,輸出結果如下:
ZhangSan
LiSi
- 在第 1 行,建立函式 create_full_name,該函式能夠接受關鍵字引數
- 該函式被呼叫時,所有關鍵字引數被合併成一個字典,被賦值給引數 kw_args
- kw_args 的型別是字典,它包含了所有的關鍵字引數
- 在第 2 行,檢查 kw_args 中是否包含引數 full_name
- 在第 3 行,從 kw_args 中獲取引數 full_name 的值
- 在第 4 行,返回 full_name
- 在第 6 行,檢查 kw_args 中是否包含引數 first_name 和 last_name
- 在第 7 行,從 kw_args 中獲取引數 first_name 的值
- 在第 8 行,從 kw_args 中獲取引數 last_name 的值
- 在第 9 行,根據 first_name 和 last_name 計算 full_name
- 在第 10 行,返回 full_name
- 在第 12 行,通過 “直接給出人的姓名” 的方式呼叫 create_full_name
- 傳遞關鍵字引數 full_name = ‘ZhangSan’
- 關鍵字引數被合併入一個字典 kw_args
- 字典 kw_args 中包含一條鍵值對
- 在第 12 行,通過 “分別給出人的姓和名” 的方式呼叫 create_full_name
- 傳遞關鍵字引數 first_name = ‘Li’、last_name = ‘Si’
- 關鍵字引數被合併入一個字典 kw_args
- 字典 kw_args 中包含兩條鍵值對
5. 小結
這節課我們學習了函式的引數,引數這個概念是函式使用中不可缺少的一環。在函式定義時的引數叫做"形參",而在函式呼叫時的引數叫做"實參"。一定要分清這兩個概念。