python基礎之 函式的引數

ckxllf發表於2020-05-06

  一、形參和實參是什麼?

  函式的引數分為形式引數和實際引數,簡稱形參和實參:

  形參即在定義函式時,括號內宣告的引數。形參本質就是一個變數名,用來接收外部傳來的值。

  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就是用來接收多餘的關鍵字實參的,如果多餘的不是關鍵字實參,會報錯。你再用命名關鍵字引數,限制必須關鍵字實參傳值,沒有意義。

    鄭州較好的婦科醫院

在這裡插入圖片描述

  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是約定俗成的。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69945560/viewspace-2690141/,如需轉載,請註明出處,否則將追究法律責任。

相關文章