函數:一個工具,隨調隨用
降級代碼冗余
增加代碼的復用性,提高開發效率,為了不成為cv戰士
提高程序擴展性
函數有兩個階段:定義階段,調用階段。
定義時:只檢查函數體內代碼語法,不執行函數體內代碼。
函數參數:
參數分形參、實參
形參:函數定義時括號內的參數
實參:函數調用時括號內的參數
形參相當於變量,實參相當於變量的值。
定義時:
def func(a, b, c):
pass
a, b, c為形參
調用時:
func(1, 2, 3)
1, 2, 3 為實參
形參:
只在被調用時,才分配內存單元。調用結束,立刻釋放所分配的內存。
形參只在函數內部有效。
實參:
可以是:常量、變量、表達式、函數。
進行函數調用時,實參必須是確定的值。
位置參數:
位置形參:函數定義時,從左往右寫的參數,比如上面的 a, b , c
位置實參:函數調用時,從左往右寫的參數, 比如上面的 1,2,3
位置形參定義多少個,調用時位置實參必須寫上多少個,多一個少一個都不行。
關鍵參數:
正常情況下,給函數傳參數,要按順序。如果不想按順序,就用關鍵參數。
指定參數名的參數,就叫做關鍵參數。
函數調用時:func(a=1, b=2), 這種指定了參數名的參數,就是關鍵參數。
調用函數時,關鍵參數可以和位置參數一起用,但是關鍵參數必須在位置參數的后面。不然會報錯。
默認參數:
函數定義時,默認參數必須在位置形參的后面。
函數調用時,指定參數名的參數,叫關鍵參數。
而在函數定義時,給參數名指定值的時候,這個參數叫做默認參數。
關鍵參數,和默認參數兩個參數寫法一樣,區別在於:
關鍵參數是在函數調用時,指定實參的參數名,也可以說指定值的參數名。
默認參數是在函數定義時,指定參數名的值。
寫法:
def (a, b=100):
pass
定義時,有默認參數的話,調用時,這個實參可以不寫。如果實參不寫的話,這個形參的參數值是他的默認值。
動態參數:*args **kwargs
*args
針對函數定義時的*:
def func(a, b, *args):
pass
*args會接收函數調用時,傳入的多余的位置實參。
*args 是一個元組
例子:
func(1, 2, 3, 4, 5, 6) 函數調用,因為函數定義時,*args前面有形參a, 形參b, *args就接收調用時多余的位置實參
a為1, b為2, *args 為: (3, 4, 5, 6),是一個元組。
針對函數調用時的 *:
func(1, 2, *[1, 2, 3, 4]) == func(1, 2, 1, 2, 3, 4)
函數調用時有*, 就應該立馬將*后面的列表,元組,字符串之類的迭代器,打散成位置參數來看。
注意,如果 *后面是一個字典的話,那么打散成的位置參數就是字典的key
*可以看做是for循環。
形參中 *args 只能接收多余的位置實參,成為一個元組。不能接收關鍵實參。
**kwargs:
針對函數定義時,站在形參的角度看 **:
接收多余的關鍵實參,成為一個字典dict。
字典的key是關鍵實參的變量名,字典的value是關鍵實參的值。
將字典交給**后面的變量名,這里是kwargs
站在實參的角度看 ** :
d = {'x':1, 'y':2, 'z':333}
func(**d) # 等價於func(x=1,y=2,z=333)
函數調用時,**后面可以接一個字典,然后**會把字典打散成關鍵參數的形式,也就是key=value的形式。
函數定義時:
從左往右:位置形參 > *args > 默認參數 > **kwargs
位置形參 > 默認參數 > *args > **kwargs 也可以。
因為函數調用時給的實參滿足了位置形參、默認參數之后,會把多余的位置實參給args。這樣並不會報錯。
但是 **kwargs 必須在 *args后面
默認形參必須在位置形參后面
函數調用時:
從左到右:位置實參 > *args > 關鍵參數 > ** kwargs
因為 * args 在函數調用時,會被打散成位置實參,而關鍵參數必須在位置實參的后面,否則會報錯。SyntaxError: positional argument follows keyword argument
*args 必須在 **kwargs后面, 否則會報語法錯誤:SyntaxError: iterable argument unpacking follows keyword argument unpacking