python函數之參數(python3.5)

函數定義

函數是對能完成某種功能的語句塊的封裝。由函數名、參數列表和多語句構成的語句塊組成,定義方式以下:python

def func_name(argrs):

  語句塊

說明:數組

  1. def語句用於函數定義,def語句的做用是生成一個函數對象,而且將其賦值給函數名;
  2. 函數定義時的參數列表稱之爲形參
  3. 語句塊中通常會包含一個return語句,返回函數調用的結果;若是沒有那麼函數在其末尾自動執行 return None


函數調用

ret = func_name(args)

說明:app

  1. def語句只是定義一個函數對象,執行函數須要調用
  2. 函數調用的方式,func_name(args)
  3. 函數調用時寫在括號中的參數稱之爲實參,分爲位置參數和關鍵字參數,它們的書寫形式分別爲valuename=value。下面的示例中,print函數調用,一、2爲位置參數(也能夠是已定義的變量),sep = '\n' 爲關鍵字參數
>>> print(1,2,sep='\n')
1
2

>>> a = 1, b= 2

>>> print(a, b, sep='\n')
1
2

函數返回函數

  • 遇到return語句函數直接返回,後面的語句再也不被執行
  • 函數只能返回單值,這個值能夠是任意的數據類型

函數參數之形參

形參中可能包含四種參數(排序分前後):位置參數、可變位置參數、keyword-only參數、可變keyword-only參數。ui

  1. 參數就是變量標識符,命名規範相同。
  2. 可變位置參數用‘*’加標識符表示,如*args;可變keyword-only參數用‘**’加標識符表示,如**kwargs。可變參數用於收集任意多基於位置或者關鍵字的參數。
  3. 四種參數在形參列表中都是可選的,可是它們的相對位置不變。
  4. 位置參數:經過位置進行匹配,把實參的值經過賦值傳給對應位置的形參參數名,從左到右進行匹配。位置參數也能夠經過 name=value 的形式傳參,參數按照名稱匹配,順序無關。
    >>> def f4(a, b):
    ...     print('a =', a)
    ...     print('b =', b)
    ... 
    >>> c, d = 1, 2
    >>> f4(c, d)  #對應位置匹配,至關於實參分別爲對應位置形參變量賦值,a=c, b=d
    a = 1 
    b = 2

    >>> f4(b = d, a = c)
    a = 1
    b = 2

     

     注意:由於參數是經過賦值傳遞的,全部實參和形參從某種意義上講是在共享對象。若是傳遞的是可變對象,那麼函數對形參的原地修改可能會影響到實參。                                    spa

  5. keyword-only參數: 實參只能是 name = value 的形式,經過 name與形參中的變量進行匹配,實參順序不影響匹配。
    >>> def f5(*, a, b):    #‘*’的意義在於,在語法上將a、b定義爲keyword-only參數
    ...     return a, b
    ... 
    >>> f5(1,2)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: f1() takes 0 positional arguments but 2 were given
    #keyword-only參數不能經過位置進行匹配
    >>> f5(b=1, a=2) (2, 1) 
    >>> def f5(*args, a, b):
    ...     print('args =', args)
    ...     print('a =', a)
    ...     print('b =', b)
    ... 
    >>> c = 3
    >>> d = 4 >>> f5(1, 2, a=c, b=d) args = (1, 2) a = 3 b = 4
    #形參中的*args參數收集任意多個未匹配的位置參數到一個tuple。
    >>> f2(a=1, 2, b=4)
      File "<stdin>", line 1
    SyntaxError: positional argument follows keyword argument
    #實參的位置參數必須位於關鍵字參數以前

    形式上,位置參數和keyword-only參數沒有區別,爲了定義keyword-only參數必須將其放到*或者*args後。code

  6. 位置參數和keyword-only參數在定義時,能夠定義一個默認參數值。在調用中若是對應參數沒有實參傳入,則使用默認值。
    >>> def f6(p1, p2=0, *, k1=[], k2):    #定義中p2 和 k1有默認值,傳參的時候能夠缺省,可是p1和k2必須有相應的參數傳入,不然會報錯
    ...     print('p1 =', p1)
    ...     print('p2 =', p2)
    ...     print('k1 =', k1)
    ...     print('k2 =', k2)
    ... 
    >>> f6(1, k2=3) #1位置匹配到形參中的p1, k2匹配形參中的k2, p2 和 k1使用定義中規定的默認值 p1 = 1 p2 = 0 k1 = [] k2 = 3
    >>> f6(p1 = 1, p2 = 2). #位置參數也能夠經過name = value的形式傳遞,經過name進行匹配,傳參順序無關 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: f6() missing 1 required keyword-only argument: 'k2'
    #缺乏keyword-only參數:‘k2’
    >>> f6(1,p2 = 2, k2 = 3) # 1經過位置匹配傳給p1, p2 和 k2分別經過name匹配傳遞,沒有k1對應的實參傳入,使用默認值
    p1 = 1
    p2 = 2
    k1 = []
    k2 = 3
    >>> f6(1,2, k2 = 3, k1 = 4) # 4個形參都有對應實參傳入,因此不須要使用默認值 p1 = 1 p2 = 2 k1 = 4 k2 = 3

     

  7. 位置參數中,有默認值的參數的定義必須放在非默認值參數以後,不然會報語法錯誤。keyword-only參數無此要求。
    >>> def f7(a=1, b): ... return a,b ... File "<stdin>", line 1 SyntaxError: non-default argument follows default argument 

函數參數之實參

實參(位置參數和關鍵字參數)和形參(位置參數、可變位置參數、keyword-only參數、可變keyword-only參數)之間的匹配順序能夠這樣理解:對象

  1. 首先實參中的位置參數和形參的位置參數匹配
  2. 而後實參中的關鍵字參數和形參中的位置參數和keyword-only參數經過標識符(name)匹配
  3. 實參中多餘的位置參數放入形參的可變位置參數,生稱一個元組
  4. 實參中多餘的關鍵字參數放入形參的可變keyword-only參數, 生成一個字典
  5. 沒有實參匹配的形參使用默認值

實參中參數的解構

  • 函數調用時,能夠在集合類型前使用 * 或者 ** ,把集合元素中的結構解開,提取出全部的參數做爲函數的實參
  • 非字典類型使用 * 解構成位置參數
  • 字典類型使用 ** 解構成關鍵字參數
  • 提取出來的元素數目和類型要和形參需求匹配

默認參數

默認參數是在def語句運行時評估並保存的,而不是在函數調用時。在內部講,python會將全部默認參數組合生成一個元組對象,做爲函數的一個屬性(__defaults__)保存。由於屬性是附加到函數自己的,全部對該函數的調用都使用了同一個對象,因此對可變默認參數的修改要慎重。blog

>>> def saver(x = []):
...     x.append(1)
...     print(x)
... 
>>> saver.__defaults__  #對象屬性的查看方式,應用該對象的變量名加點加屬性名
([],)
>>> saver()
[1]
>>> saver.__defaults__
([1],)
>>> saver()
[1, 1]

 

若是這不是你所想要的行爲能夠將默認參數值的表達式移到函數體內:排序

>>> def saver(x=None): ... x = x or []  #若是沒有參數傳入的話,x默認爲None,or運算返回後面的空列表 ... x.append(1) ... print(x) ... >>> saver() [1] >>> saver() [1]

or運算,從左到右計算表達式返回第一個遇到的真值,若是全部值都爲False,那麼返回最後一個值。若是傳入的x參數爲0或者空列表或者空集合等,那麼就都會替換爲空列表[]了,這可能也不符合預期,咱們可使用if語句:

>>> def saver(x=None): ... if x is None: ... x = [] ... x.append(1) ... print(x)
相關文章
相關標籤/搜索