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 来源:知乎 著做权归做者全部。商业转载请联系做者得到受权,非商业转载请注明出处。 -----------------------------------------------------------   命名关键字从上面例子来看,和位置参数有着明显的不一样。命名关键字参数更加灵活一些。不过如今看起来仍是有些晕,在后续的学习中看能不能把命名关键字参数吃透。
相关文章
相关标签/搜索