形參和實參
- 形參即形式參數,函數完成其工作時所需的信息。形參不占用內存空間,只有在被調用時才會占用內存空間,調用完了即被釋放。
- 實參即實際參數,調用函數時傳給函數的信息。
# -*- coding: utf-8 -*-
def main(name): # name 即為形參 print "hello world %s" % name print "hello world {name}".format(name=name) return name
main("python") # python 即為實參
上述而言:在調用函數並傳入參數即main("python"),將實參"python"傳遞給函數main(),這個值就被存儲在形參name中。
函數的參數傳遞(實參的傳遞方式)
- 位置傳參:在調用函數進行傳參時,實際參數(實參)與形式參數(形參)的對應關系是按照位置來依次對應的。
- 序列傳參:在調用函數進行傳參時,實參為序列,用"*"將序列拆解后再進行位置傳參。實參和形參通過序列傳遞和匹配。
- 關鍵字傳參:在調用函數進行傳參時,按照形參的名稱給形參賦值,即傳遞給函數的是鍵值對。實參和形參按名稱進行匹配。
- 字典關鍵字傳參:在調用函數進行傳參時,實參為字典,用"**"將字典拆解后再進行關鍵字傳參。
位置傳參
# 位置傳參,實參與形參需要一一對應,不可多也不可少。 def main(name, age, hobby): content = "My name is %s,I'm %d years old,my hobby is %s" % (name, age, hobby) return content content = main("張三", 26, "playgame")
序列傳參
# 序列傳參,序列里的元素必須和形參的數量保持一致。將序列拆解后再按照位置傳參方式進行傳參。 def main(name, age, hobby): content = "My name is %s,I'm %d years old,my hobby is %s" % (name, age, hobby) return content info = ["張三", 26, "playgame"] content = main(info[0], info[1], info[2]) # 這是位置傳參,實參的值與形參的值按照順序一一對應 content = main(*info) # 這是序列傳參,將info拆解后再依次傳入 name="張三" age=26 hobby="playgame"
關鍵字傳參
# 關鍵字傳參,實參與形參無需一一對應,不可多也不可少。實參和形參按照形參名進行匹配,可以不按照位置進行匹配。 def main(name, age, hobby): content = "My name is %s,I'm %d years old,my hobby is %s" % (name, age, hobby) return content content = main(age=28, name="王五", hobby="fishing") # 在實參中的將名稱和值關聯起來,所以在傳入時無需考慮順序。
字典關鍵字傳參
# 字典關鍵字傳參,函數括號里不能直接寫字典,前面應該加上 "**" 表示拆解字典。 # 字典的鍵名要在形參中存在且和形參名必須一致。字典的鍵名必須為字符串。 def main(name, age, hobby): content = "My name is %s,I'm %d years old,my hobby is %s" % (name, age, hobby) return content info = {"age": 28, "name": "王五", "hobby": "fishing"} content = main(**info) content = main(**{"age": 28, "name": "王五", "hobby": "fishing"})
以上傳參方式綜合傳參:函數的傳參方式在能確定形參能唯一匹配到相應實參的情況下可以任意組合
位置傳參和關鍵字傳參混合使用:在沒有參數組(即沒有*args和**kwargs)的情況下,實參的數量必須與形參的數量一致。
def main(name, age, hobby): content = "My name is %s,I'm %d years old,my hobby is %s" % (name, age, hobby) return content # content = main(name="張三", 28, hobby="fishing") # 報錯:位置傳參必須寫在關鍵字傳參的左邊 # content = main("張三", 28, age="fishing") # 報錯:同一個參數不能兩次或者多次傳值,只能傳一次 content = main("張三", age=28, hobby="fishing")
四種傳參混在一起使用:通常位置傳參和序列傳參先傳遞,其次是關鍵字傳參和字典關鍵字傳參。
def main(name, sex, age, score, hobby): print name, sex, age, score, hobby return "hello python success!!" con = main("張三", *["男", 28], hobby="fishing", **{"score": 90})
函數的形參定義方式(形參的接收方式)
- 位置形參:上面的示例是實參的傳遞方式,形參全是位置形參。上面是傳遞參數(實參),下面是接收參數(形參)。
- 單星號元組形參:接收傳入的多余的位置參數,被args接收。
- 雙星號字典形參:接收傳入的多余的關鍵字參數,被kwargs接收。
位置形參
# 所有的形參全都一一列舉出來 def 函數名(形參名1,形參名2,...,形參名n): 語句塊
單星號元組形參
def 函數名(*args): 語句塊
def main(name, *args): print name, args, type(args) return "success!!!"
main("張三", "男", "playgame") main("張三", {"sex": "男"}, "dancing") # 即使傳入字典,字典當成整體也會以元組的方式被接收 main("張三", ["hello", "world"], "dancing") main("張三", *["hello", "world"]) # 相當於遍歷該列表,逐個添加至列表並且轉為元組,*args接收。 main("張三", *"hello") # 相當於遍歷該字符串,逐個添加至列表並且轉為元組,*args接收。
# *args 表示創建一個名為 args 的空元組,該元組可接受任意多個外界傳入的非關鍵字實參。 # *args 將多於的實參,以位置參數的方式傳入,以元組的形式接收。保存在args元組中。*args名稱可以自己隨意取,如*word。 # 參數收集的本質就是一個元組, Python 會將傳給 args 參數的多個值收集成一個元組,以元組為對象進行參數傳遞。 # 輸出為: # 張三 ('男', 'playgame') <type 'tuple'> # 張三 ({'sex': '男'}, 'dancing') <type 'tuple'> # 張三 (['hello', 'world'], 'dancing') <type 'tuple'> # 張三 ('hello', 'world') <type 'tuple'> # 張三 ('h', 'e', 'l', 'l', 'o') <type 'tuple'>
雙星號字典形參
def 函數名(**kwargs): 語句塊
def main(name, **kwargs): print name, kwargs, type(kwargs) return "success!!!"
main("張三", sex="男", age=28) main(name="張三", sex="男", age=28) main(name="張三", **{"sex": "男", "age": 28}) # **kwargs 表示創建一個名為 kwargs 的空字典,該字典可接受任意多個外界傳入的關鍵字實參。 # **kwargs 將多於的實參,以關鍵字參數的形式傳入,以字典的形式接收。保存在kwargs字典中。 # 輸出為: # 張三 {'age': 28, 'sex': '\xe7\x94\xb7'} <type 'dict'> # 張三 {'age': 28, 'sex': '\xe7\x94\xb7'} <type 'dict'> # 張三 {'age': 28, 'sex': '\xe7\x94\xb7'} <type 'dict'>
單星號元組形參與雙星號字典形參混合使用
# 當在函數定義參數時,同時定義*args與**kwargs時,可以接收在調用函數時傳入的任何參數(任意位置傳參和關鍵字傳參)。 # 多余的位置參數,傳入函數,以元組的方式被存儲在*args中。多余的關鍵字參數,傳入函數,以字典的方式被存儲在**kwargs中。 def func(*args, **kwargs): pass def main(x, y, *args, **kwargs): print x, y # 結果: 100 200 print args, type(args) # 結果: (300, ['hello', 'python']) <type 'tuple'> print kwargs, type(kwargs) # 結果: {'age': 28, 'sex': '\xe7\x94\xb7'} <type 'dict'> return "success!!!"
main(100, 200, 300, ["hello","python"], age=28, sex="男")
def main(a, b, *args, **kwargs): print a,b # 結果:100 200 print args # 結果:(300, 'A', 'B') print kwargs # 結果:{'c': 'C', 'd': 'D'} main(100, 200, 300, *"AB", **{"c": "C", "d": "D"})
函數的缺省參數(默認參數)
定義函數時我們可以給參數傳遞默認值,當調用函數時沒有傳遞該參數值時使用默認參數值。帶默認值的參數稱為默認參數,無默認值的參數稱為必需參數,調用函數時必需參數必填,默認參數選填。
缺省規則
- 缺省參數必須自右至左依次存在。即默認參數一定在必需參數之后。即 score 在 name 之后。
- 缺省參數可以有0個,1個,多個,甚至全部都是缺省參數。
- 缺省參數的綁定對象存在於函數內,同函數的生命周期一致。
- 函數體里面如果對缺省參數操作了,則會保存,下次調用時候,是保存的最新的了。
def 函數名(形參名1 = 默認實參1,形參名2 = 默認實參2,...): 語句塊
def main(name, score=60, *args, **kwargs): print name, score, args, kwargs return "success!!!"
main("張三", sex="男") # 不給默認參數傳值時,使用默認參數值 main("張三", 80, sex="男") # 當給默認參數傳值時,則覆蓋 main("張三", 80, 90, sex="男") # 多余的值用*args 和 **kwargs 接收 # 輸出為: # 張三 60 () {'sex': '\xe7\x94\xb7'} # 張三 80 () {'sex': '\xe7\x94\xb7'} # 張三 80 (90,) {'sex': '\xe7\x94\xb7'}
def main(a, lst=[]): lst.append(a) print(lst) l = [1, 2, 3] main(5, l) # 結果:[1, 2, 3, 5] main(6, l) # 結果:[1, 2, 3, 5, 6] main(1.1) # 結果:[1.1] main(2.2) # 結果:[1.1, 2.2]