zoukankan      html  css  js  c++  java
  • Day5

    引子:
    对于关键字参数,调用时可以传入任意个不受限制的关键字参数,至于到底传入了哪些,就需要在函数内部通过【函数里定义的关键字参数】检查,例子里就是通过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
    来源:知乎
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    -----------------------------------------------------------  
    命名关键字从上面例子来看,和位置参数有着明显的不同。命名关键字参数更加灵活一些。不过现在看起来还是有些晕,在后续的学习中看能不能把命名关键字参数吃透。
  • 相关阅读:
    springboot配置大全
    springboot上传文件时500错误,提示临时目录无效
    Springboot上传文件临时目录无效
    SpringBoot 文件上传临时文件路径问题
    SpringBoot 上传文件到linux服务器 异常java.io.FileNotFoundException: /tmp/tomcat.50898……解决方案
    tomcat下的work目录和temp目录
    Http协议报文格式
    multipart/form-data与application/octet-stream的区别、application/x-www-form-urlencoded
    Nginx的三种应用场景介绍
    SpringBoot: 浅谈文件上传和访问的坑 (MultiPartFile)
  • 原文地址:https://www.cnblogs.com/konggg/p/8989168.html
Copyright © 2011-2022 走看看