您好,登錄后才能下訂單哦!
一、形參和實參是什么?
函數的參數分為形式參數和實際參數,簡稱形參和實參:
形參即在定義函數時,括號內聲明的參數。形參本質就是一個變量名,用來接收外部傳來的值。
def func(x,y): #x和y為形參
print(x,y)
實參即在調用函數時,括號內傳入的值,值可以是常量、變量、表達式或三者的組合。
func(1,2) #1和2為實參
形參和實參的關系:
在調用階段,實參(變量值)會賦值給形參(變量名)
二、形參與實參的具體使用
1、兩種形參的區別
(1)位置形參
在定義函數時,按照從左到右的順序依次定義形參,稱為位置形參,凡是按照這種形式定義的形參都必須被傳值
def register(name,age,sex): #定義位置形參:name,age,sex,三者都必須被傳值
print('Name:{} Age:{} Sex:{}'.format(name,age,sex))
(2)默認形參
默認形參調用時,可以不傳值,那么就是默認值,傳值就覆蓋默認值。
>>> def register(name,age,sex='male'): #默認sex的值為male
... print('Name:{} Age:{} Sex:{}'.format(name,age,sex))
...
需要注意:
默認參數必須在位置參數之后
默認參數的值僅在函數定義階段被賦值一次
默認參數的值通常應設為不可變類型
def foo(n,arg=[]):
arg.append(n)
return arg
foo(1)
[1]
foo(2)
[1, 2]
foo(3)
[1, 2, 3]
每次調用是在上一次的基礎上向同一列表增加值,修改如下
def foo(n,arg=None):
if arg is None:
arg=[]
arg.append(n)
return arg
foo(1)
[1]
foo(2)
[2]
foo(3)
[3]
2、兩種實參的區別
(1)位置實參
在調用函數時,按照從左到右的順序依次定義實參,稱為位置實參,凡是按照這種形式定義的實參會按照從左到右的順序與形參一一對應
def register(name,age,sex): #定義位置形參:name,age,sex,三者都必須被傳值
print('Name:{} Age:{} Sex:{}'.format(name,age,sex))
register('吳晉丞',18,'男') #定義位置實參:'吳晉丞',18,'男',按照順序和形參相對應
(2)關鍵字實參
在調用函數時,實參可以是key=value的形式,稱為關鍵字參數,凡是按照這種形式定義的實參,可以完全不按照從左到右的順序定義,但仍能為指定的形參賦值
>>> register(sex='male',name='lili',age=18)
Name:lili Age:18 Sex:male
需要注意在調用函數時,實參也可以是按位置或按關鍵字的混合使用,但必須保證關鍵字參數在位置參數后面,且不可以對一個形參重復賦值
>>> register('lili',sex='male',age=18) #正確使用
#錯誤示例:
>>> register(name='lili',18,sex='male') #SyntaxError:關鍵字參數name=‘lili’在位置參數18之前
>>> register('lili',sex='male',age=18,name='jack') #TypeError:形參name被重復賦值
3、可變長參數
參數的長度可變指的是在調用函數時,實參的個數可以不固定,而在調用函數時,實參的定義無非是按位置或者按關鍵字兩種形式,這就要求形參提供兩種解決方案來分別處理兩種形式的可變長度的參數
(1)可變長位置參數在形參和實參中的應用
形參中的應用
如果在最后一個形參名前加*號,那么在調用函數時,溢出的位置實參,都會被接收,以元組的形式保存下來賦值給該形參
>>> def foo(x,y,z=1,*args): #在最后一個形參名args前加*號
... print(x)
... print(y)
... print(z)
... print(args)
...
>>> foo(1,2,3,4,5,6,7) #實參1、2、3按位置為形參x、y、z賦值,多余的位置實參4、5、6、7都被*接收,以元組的形式保存下來,賦值給args,即args=(4, 5, 6,7)
1
2
3
(4, 5, 6, 7)
實參中的應用
如果我們事先生成了一個列表(也可以是元組、字符串),仍然是可以傳值給*args的
>>> def foo(x,y,*args):
... print(x)
... print(y)
... print(args)
...
>>> L=[3,4,5]
>>> foo(1,2,*L) # *L就相當于位置參數3,4,5。foo(1,2,*L)就等同于foo(1,2,3,4,5)
1
2
(3, 4, 5)
(2)可變長關鍵字參數在形參和實參中的應用
形參中的應用
如果在最后一個形參名前加**號,那么在調用函數時,溢出的關鍵字參數,都會被接收,以字典的形式保存下來賦值給該形參
>>> def foo(x,**kwargs): #在最后一個參數kwargs前加**
... print(x)
... print(kwargs)
...
>>> foo(y=2,x=1,z=3) #溢出的關鍵字實參y=2,z=3都被**接收,以字典的形式保存下來,賦值給kwargs
1
{'z': 3, 'y': 2}
實參中的應用
如果我們事先生成了一個字典,仍然是可以傳值給**kwargs的
>>> def foo(x,y,**kwargs):
... print(x)
... print(y)
... print(kwargs)
...
>>> dic={'a':1,'b':2}
>>> foo(1,2,**dic) #**dic就相當于關鍵字參數a=1,b=2。foo(1,2,**dic)等同foo(1,2,a=1,b=2)
1
2
{'a': 1, 'b': 2}
4、命名關鍵字參數(了解)
想要限定函數的調用者必須以key=value的形式傳值,Python3提供了專門的語法:需要在定義形參時,用*號作為一個分隔符號,*號之后的形參稱為命名關鍵字參數。對于這類參數,在函數調用時,必須按照key=value的形式為其傳值,且必須被傳值。
>>> def register(name,age,*,sex,height): #sex,height為命名關鍵字參數
... pass
...
>>> register('lili',18,sex='male',height='1.8m') #正確使用
#錯誤示例:
>>> register('lili',18,'male','1.8m') # TypeError:未使用關鍵字的形式為sex和height傳值
>>> register('lili',18,height='1.8m') # TypeError沒有為命名關鍵字參數height傳值。
命名關鍵字參數也可以有默認值(注意:這個不叫默認形參),從而簡化調用
>>> def register(name,age,*,sex='male',height):
pass
如果形參中已經有一個*args了,命名關鍵字參數就不再需要一個單獨的*作為分隔符號了,而是\*args作為分隔符號,后面是命名關鍵字參數
>>> def register(name,age,*args,sex='male',height):#sex,height仍然為命名關鍵字參數
有人可能還會問如果是**kwargs呢?是不是以**kwargs為分隔符?
答:這樣會報錯,這樣也沒有什么用,因為**kwargs就是用來接收多余的關鍵字實參的,如果多余的不是關鍵字實參,會報錯。你再用命名關鍵字參數,限制必須關鍵字實參傳值,沒有意義。
鄭州較好的婦科醫院 http://www.kd0371.com/
5、組合使用
綜上所述所有參數可任意組合使用,但形參定義順序必須是:位置參數、默認參數、\*args、命名關鍵字參數、**kwargs.
實參的定義順序可以是:位置實參、*、關鍵字參數、**:
func(111,*(333,444),y=222,**{'a':555,'b':666})
#只要*和**打散之后遵循位置實參在關鍵字參數左邊即可。*相當于一堆位置實參,**相當于一堆關鍵字參數
可變參數*args與關鍵字參數**kwargs通常是組合在一起使用的,如果一個函數的形參為*args與**kwargs,那么代表該函數可以接收任何形式、任意長度的參數
>>> def wrapper(*args,**kwargs):
... pass
在該函數內部還可以把接收到的參數傳給另外一個函數(這在4.6小節裝飾器的實現中大有用處)
>>> def func(x,y,z):
... print(x,y,z)
...
>>> def wrapper(*args,**kwargs): #(1,)元組 {'z':3,'y':2}字典
... func(*args,**kwargs) # *(1,) **{'z':3,'y':2},實參使用*和**,打散元組、字典
...
>>> wrapper(1,z=3,y=2)
1 2 3
提示: *args、**kwargs中的args和kwargs被替換成其他名字并無語法錯誤,但使用args、kwargs是約定俗成的。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。