Python函數參數列表
- 必傳參數:平時最常用的,必傳確定數量的參數
- 默認參數:在調用函數時可以傳也可以不傳,如果不傳將使用默認值
- 可變參數:可變長度參數
- 關鍵字參數:長度可變,但是需要以 key-value 形式傳參
必傳參數(位置參數)
def add(a, b): return a + b sum = add(1, 2) print(sum) # 輸出結果 3
- add 函數有兩個參數,第一個參數是 a,第二個參數是 b
- 傳入的兩個整數按照位置順序依次賦給函數的參數 a 和 b,參數 a 和參數 b 被稱為位置參數
傳遞的參數個數必須等於參數列表的數量
- 根據函數定義的參數位置來傳遞參數,要求傳遞的參數與函數定義的參數兩者一一對應
- 如果 “傳遞的參數個數” 不等於 “函數定義的參數個數”,運行時會報錯
# 錯誤栗子 def add(a, b): return a + b sum = add(1, 2, 3) # 輸出結果 sum = add(1, 2, 3) E TypeError: add() takes 2 positional arguments but 3 were given
默認參數
使用默認參數,可以簡化函數的調用,尤其是在函數需要被頻繁調用的情況下
# 必傳參數a,默認參數b def test1(a, b=3): print(a, b) test1(0) test1(0, 1)
執行結果
0 3
0 1
Python 字符串 index 函數
str.index(sub, start=None, end=None)
知識點
聲明函數時,當同時存在必傳參數和默認參數,形參的順序必須是 (必傳參數 , 默認參數),不能默認參數在前
可變參數
為什么會需要可變參數
假設需要一個 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,但函數的參數個數是不確定的,這樣就可以復用了
可變參數的表示方式
def 函數(*args): 函數體
- 該函數被設定為能夠接受可變數量的參數
- args 的類型是元組
- 調用該函數時,所有的參數被合並成一個元組
- 合並后的元組被賦值給 args,通過遍歷 args 可以訪問傳遞的參數
求和的可變參數函數栗子
# 累加的可變參數函數 def add(*args): print(args) sum = 0 for arg in args: sum += arg print('len = %d, sum = %d' % (len(args), sum)) add(1) add(1, 2) add(1, 2, 3) # 輸出結果 (1,) len = 1, sum = 1 (1, 2) len = 2, sum = 3 (1, 2, 3) len = 3, sum = 6
混合栗子
def test2(num, num2=2, *args): print(num, num2, args) test2(1) test2(1, 3) test2(1, 3, 3, 3, 3, 3, 3) test2(1, *(2, 3, 4, 5)) test2(1, *[2, 3, 4, 5])
執行結果
1 2 () 1 3 () 1 3 (3, 3, 3, 3, 3) 1 2 (3, 4, 5) 1 2 (3, 4, 5)
知識點
- args是一個元組類型
- 可變參數可不傳,也可以傳很多個值
- *(2, 3, 4, 5) ,在元組or列表前面加一個 * ,代表將里面的每個元素獨立出來,單獨作為一個形參傳進去,也稱為元組解包
不懂*(1,2,3)可以看看這段代碼
print(*(1, 2, 3, 4)) # 輸出1 2 3 4
注意點一
可變參數之前的參數不能指定參數名
# 可變參數 def myfun(a, *b): print(a) print(b) myfun(a=1, 2, 3, 4) # 輸出結果 myfun(a=1, 2, 3, 4) ^ SyntaxError: positional argument follows keyword argument
必傳參數跟在關鍵字參數后面是不允許的
注意點二
函數傳入實參時,可變參數(*
)之后的參數必須指定參數名,否則就會被歸到可變參數之中
# 可變參數 def myfun(a, *b, c=None): print(a) print(b) print(c) myfun(1, 2, 3, 4) # 輸出結果 1 (2, 3, 4) None
c 輸出了 None ,沒有拿到參數值
關鍵字傳參解決這個問題
# 可變參數 def myfun(a, *b, c=None): print(a) print(b) print(c) myfun(1, 2, 3, c=4) # 輸出結果 1 (2, 3) 4
關鍵字參數
什么是關鍵字參數
Python 允許調用函數時,以 “參數名 = 參數值” 的形式傳遞參數
def add(a, b): return a + b add(a = 1, b = 2)
"參數名 = 參數值" 形式的參數,例如 a = 1 和 b = 2,被稱為關鍵字參數
包含關鍵字參數的函數語法格式
在參數前加上符號 ** 參數表示函數可以接收關鍵字參數
def 函數(**kwargs): 函數體
- 該函數被設定為能夠接受關鍵字參數
- kwargs 的類型是字典
- 調用該函數時,所有的關鍵字參數被合並成一個字典
- 合並后的字典被賦值給 kwargs,通過訪問 kwargs 可以訪問參數名和參數值
關鍵字參數栗子
# 關鍵字參數函數栗子 def create_full_name(**kwargs): # 打印就是一個字典 print(kwargs) name = kwargs.get("name") password = kwargs.get("password") if name and password: print("name is :", name, " and password is :", password) if name and not password: print("only name is:", name) # 方式一:通過 key=value 的方式傳參 create_full_name(name="小菠蘿", password="123456") dict_ = {"name": "yy"} # 方式二:傳字典,然后加 ** 進行解包 create_full_name(**dict_) # 輸出結果 {'name': '小菠蘿', 'password': '123456'} name is : 小菠蘿 and password is : 123456 {'name': 'yy'} only name is: yy
混合栗子
def test3(a, b=2, **kwargs): print(a, b, kwargs) test3(1) test3(1, 3) test3(1, **{"key": "value"}) test3(1, 3, **{"key": "value", "key1": "val", "key2": 'val2'}) test3(1, name="yy", key="value") test3(1, 3, name="yy", key="value") test3(1, name="yy", key="value",b=222222) # test3(1, 22222,name="yy", key="value",b=222222) 會報錯,因為第二個值已經傳給默認參數b了
執行結果
1 2 {} 1 3 {} 1 2 {'key': 'value'} 1 3 {'key': 'value', 'key1': 'val', 'key2': 'val2'} 1 2 {'name': 'yy', 'key': 'value'} 1 3 {'name': 'yy', 'key': 'value'} 1 222222 {'name': 'yy', 'key': 'value'}
知識點
- kwargs 是一個字典類型
- 關鍵字參數可傳可不傳
- 傳值的時候需要傳鍵值對,如果要傳dict需要在前面加上 ** ,表示將這個dict的所有key-value當成獨立的關鍵字參數(變成 key = value)傳入到 kwargs,而修改 kwargs 不會影響原來的 dict
- 不用 dict 的話也可以直接 key=value 的寫法,如果和默認參數重名,若前面沒有傳值的話,會當成默認參數傳值;若有的話會直接報錯
- 聲明函數時,默認參數不可以放在關鍵字參數后面
- **dict ,也叫字典解包
Python 庫某個關鍵字函數栗子
這是 requests.get() 方法的最終調用函數,可以看到除了method、url是必傳參數,還能通過 kwargs 傳很多個參數
四種參數類型都有的函數
def test4(a, b=2, *args, **kwargs): print(a, b, args, kwargs) test4(1) test4(1, 1) test4(1, *(1, 2, 3, 3, 4,)) test4(1, *(1, 2, 3, 3, 4,), cc=123, c=123) lists = ["a", "b"] dicts = {"key": 123} test4(1, *lists, **dicts)
執行結果
1 2 () {} 1 1 () {} 1 1 (2, 3, 3, 4) {} 1 1 (2, 3, 3, 4) {'cc': 123, 'c': 123} 1 a ('b',) {'key': 123}