Day5 - 06 函數的參數-命名關鍵字參數

引子:
對於關鍵字參數,調用時能夠傳入任意個不受限制的關鍵字參數,至於到底傳入了哪些,就須要在函數內部經過【函數裏定義的關鍵字參數】檢查,例子裏就是經過otherinfo檢查。
        >>> def person(name,age,**otherinfo):
        ...     print('name:',name,'age:',age,'Other infomations:',otherinfo)
        ...
    例如,咱們但願檢查是否包含sex和city參數,
       >>> def person(name,age,**other):
        ...     if 'sex' in other:
        ...             pass
        ...     if 'city' in other:
        ...             pass
        ...     print('name:',name,'age:',age,'other:',other)
        ...
        >>> person('kk',12,sex='M',city='BJ')
        name: kk age: 12 other: {'city': 'BJ', 'sex': 'M'}
        >>> person('kk',12,oo='aa')
        name: kk age: 12 other: {'oo': 'aa'}
    能夠發現,調用時依然能夠傳入不受限制的關鍵字參數oo,若是要限制關鍵字參數的名字,就能夠用命名關鍵字參數。
 
命名關鍵字參數正文:
    依然使用這個例子,咱們限制關鍵字參數的名字,只接受sex和city做爲關鍵字參數,定義以下:
        >>> def person(name, age, *, sex, city):    #注意這個星號,下面詳細說。
        ...     print('name:',name,'age:',age,city)
        ... 
        >>> person('kk',13,sex='M',city='BJ')
        name: kk age: 13 BJ
       
命名關鍵字參數的使用:
    說一下這個星號。
        和關鍵字參數不一樣,命名關鍵字參數須要一個特殊分隔符* , *後面的參數都被視爲命名關鍵字參數。調用時必須傳入參數名,不然報錯,這一點與位置參數有所不一樣。當不指定參數名時,都會被函數認爲成位置參數,可是上面這個函數只有兩個位置參數,所以會報錯。
        1. *,後面的參數都被視爲命名關鍵字參數。
        2. 若是函數定義中已經有了一個可變參數,那麼可變參數後面跟着的命名關鍵字參數就再也不須要特殊分隔符*了。
        3. 命名關鍵字參數能夠有默認值,用來簡化調用。具備默認值的命名關鍵字參數在調用函數時能夠不傳入這個參數。 命名關鍵字參數默認值的定義:
            def person(name, age, *, sex='M', city):
            ……
在學習命名關鍵字時發現的問題:
    回到正文的例子,定義person函數,包含sex、city兩個命名關鍵字參數。
         >>> def person(name, age, *, sex, city):  
        ...     print('name:',name,'age:',age,city)
        ... 
        >>> person('kk',13,sex='M',city='BJ')
        name: kk age: 13 BJ    
    #在這一步,都沒有問題。不過關鍵字參數屬於擴展,因此命名關鍵字參數是否是和關鍵字參數同樣,能夠接受0個參數傳入呢?
     
        >>> person('kk',13)     #只傳入位置參數name和age,別的參數都不傳
        Traceback (most recent call last):
          File "<stdin>", line 1, in <module>
        TypeError: person() missing 2 required keyword-only arguments: 'sex' and 'city'
    #報錯了, 再次進行測試,命名關鍵字參數是否是和關鍵字參數同樣,能夠接受任意個參數傳入?(是否是隻要保證傳入了命名關鍵字參數後,能夠任意?)
   
        >>> person('kk',13,sex='M',city='BJ',Phone=110,weight=100)
        Traceback (most recent call last):
          File "<stdin>", line 1, in <module>
        TypeError: person() got an unexpected keyword argument 'Phone'
    #仍是報錯了。詭異的發現,這樣一來,命名關鍵字參數和位置參數彷佛徹底沒有區別嘛!都是強制輸入這幾個參數,缺一或者多一都不行。
       
爲何?------學事後面的參數組合就明白了(後注)。
-----------------------------------------------------------      
來自知乎:
既然已經有了位置參數,那麼這個命名關鍵字參數api設計是不是多餘的,位置參數是必傳,那麼功能上徹底能夠替代命名關鍵字參數,並且還易懂。除了調用的時候須要寫上key以外和書寫順序能夠變換意外還有什麼其餘的嗎?難道就是由於這樣會使調用者能靈活一點?
-----------------------------------------------------------      
def func1(a,  *q ,  * ,  b ,  **w)
任意形式的函數,均可以用func(*args, **kw)的形式來調用它,不管它的參數是如何定義的。其中args是一個list,kw是一個dict.
如對於函數func1,如下兩種調用方式都可:
func1( 1 , *[2,3] , b=1, **{ 'w1':2 , 'w2':3 } )
或:
func1( *[1,2,3] , **{ 'b':1, 'w1':2 , 'w2':3 } )

爲何有了必傳的位置參數,還要有必傳的命名關鍵字參數呢?
個人理解是位置參數是list中的一個必要元素,而命名關鍵字是dict中的一個必要元素。
list和dict的區別就很少說了
做者:焦大嬸 連接:https://www.zhihu.com/question/57726430/answer/302836571 來源:知乎 著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。 -----------------------------------------------------------   命名關鍵字從上面例子來看,和位置參數有着明顯的不一樣。命名關鍵字參數更加靈活一些。不過如今看起來仍是有些暈,在後續的學習中看能不能把命名關鍵字參數吃透。
相關文章
相關標籤/搜索