• *args和**kwargs:


    *args和**kwargs:
    
    这一节我们要讨论Python里*和**的特殊含义,它们都和函数有关但是在函数调用时和函数声明时却有着不同的行为。
    
    
    一般说来,无论是函数调用还是声明,单个星号表示有元组(或是列表)“出现”
    
    而两个星号则代表附近有字典出没
    
    
    函数调用里的*和**
    
    
    我们来重新看一下之前的例子check_web_server函数,下面是函数的签名:
    
    
    def check_web_server(host,port,path):
    
    用check_web_server('127.0.0.1',8000,'/admin/')即可调用这个函数,那要是这些信息在一个三元组里的话怎么办?
    
    host_info=('wwww.python.org',80,'/')
    print host_info[0]
    print host_info[1]
    print host_info[2]
    
    C:Python27python.exe C:/Users/TLCB/PycharmProjects/untitled/mycompany/Django/a3.py
    wwww.python.org
    80
    /
    
    host_info=('wwww.python.org',80,'/')
    def check_web_server(host,port,path):
        print 'host',host
        print 'port',+port
        print 'path',path
    check_web_server(host_info[0],host_info[1],host_info[2])
    
    
    
    C:Python27python.exe C:/Users/TLCB/PycharmProjects/untitled/mycompany/Django/a3.py
    host wwww.python.org
    port 80
    path /
    
    
    然后这种写法既不可扩展(要是函数有超过一打的参数怎么办?)也不好看,这时单星号就可以解决我们的问题,
    
    因为当调用函数时,表达式在计算一个带星号前缀的元组或列表时会将其"打开".
    
    所以下面的例子和上面的代码是等价的:
    
    host_info=('wwww.python.org',80,'/')
    def check_web_server(host,port,path):
        print 'host',host
        print 'port',+port
        print 'path',path
    check_web_server(*host_info)
    
    C:Python27python.exe C:/Users/TLCB/PycharmProjects/untitled/mycompany/Django/a3.py
    host wwww.python.org
    port 80
    path /
    
    这样的写法就明显要干净和优雅得多
    
    
    而双信号对字典的用法也是类似的,现在我们来创建一个具有和('www.python.org',80,'/')相似的字典:
    
    
    host_info={'host':'wwww.python.org','port':80,'path':'/'}
    def check_web_server(host,port,path):
        print 'host',host
        print 'port',+port
        print 'path',path
    check_web_server(**host_info)
    
    C:Python27python.exe C:/Users/TLCB/PycharmProjects/untitled/mycompany/Django/a3.py
    host wwww.python.org
    port 80
    path /
    
    函数签名里的*和** 虽然看着相似但作用却完全不同:它们让Python得以支持变长参数,
    
    
    有时也称为"varargs".即函数可以接受任何数量的参数:
    
    
    def daily_sales_total(*all_sales):
        total =0
        for each_sale in all_sales:
            total +=each_sale
        return total
    print daily_sales_total()
    
    C:Python27python.exe C:/Users/TLCB/PycharmProjects/untitled/mycompany/Django/a5.py
    0
    
    
    def daily_sales_total(*all_sales):
        total =0
        for each_sale in all_sales:
            total +=each_sale
        return total
    print daily_sales_total(1,3,5)
    
    
    C:Python27python.exe C:/Users/TLCB/PycharmProjects/untitled/mycompany/Django/a5.py
    9
    
    不管你向这个函数传递多少参数,它都能够处理。all_salves就是一个包含了所有参数的元组
    
    你还可以把普通参数和变长参数混在一起使用,这时vararg就会捕获所有剩下的参数,
    
    例如在这个假设的check_web_server函数定义就能接受额外的参数了。
    
    注意:
    
    在函数定义里使用变长参数时,所有必须出现的参数一定先出现,然后是默认值的参数,最后才是变成参数。
    
    def check_web_server(host,port,path,*args):
        print 'host',host
        print 'port',port
        print 'path',path
        for s in args:
            print s
    
    check_web_server('192.168.137.2','80','/app',3,4,5,6,7)
    
    
    C:Python27python.exe C:/Users/TLCB/PycharmProjects/untitled/mycompany/Django/a5.py
    host 192.168.137.2
    port 80
    path /app
    3
    4
    5
    6
    7
    
    类似地,你也可以在函数签名里用双星号来接受任意数目的关键字参数,它们会在函数被调用的时候
    
    导入到一个字典里去。
    
    def check_web_server(host,port,path,*args,**kwargs):
        print 'host',host
        print 'port',port
        print 'path',path
        for s in args:
            print s
        print '---------------'
        print 'xx',kwargs['xx']
        print 'yy', kwargs['yy']
        print 'zz', kwargs['zz']
    
    check_web_server('192.168.137.2','80','/app',3,4,5,6,7,xx='wwww.python.org',yy='80',zz='/')
    
    
    
    C:Python27python.exe C:/Users/TLCB/PycharmProjects/untitled/mycompany/Django/a5.py
    host 192.168.137.2
    port 80
    path /app
    3
    4
    5
    6
    7
    ---------------
    xx wwww.python.org
    yy 80
    zz /
    
    Process finished with exit code 0
    
    
    实际上,还有一种全部由变长参数组成的所谓"通用"Python方法签名
    
    
    def f(*args,**kwargs):
        for s in args:
            print s
        print '---------------'
        print kwargs['x']
    f('1','2','aa',x='ff',y='gg')
    
    C:Python27python.exe C:/Users/TLCB/PycharmProjects/untitled/mycompany/Django/a6.py
    1
    2
    aa
    ---------------
    ff
    
    
    def f(*args,**kwargs):
        for s in args:
            print s
        print '---------------'
        print kwargs['x']
        print kwargs['y']
    f('1','2','aa',x='ff',y='gg')
    
    C:Python27python.exe C:/Users/TLCB/PycharmProjects/untitled/mycompany/Django/a6.py
    1
    2
    aa
    ---------------
    ff
    gg
    
    
    
    def f(*args,**kwargs):
        for s in args:
            print s
        print '---------------'
        print kwargs['x']
        print kwargs['y']
    f('1','2','aa',x='ff',y='gg',z)
    
    C:Python27python.exe C:/Users/TLCB/PycharmProjects/untitled/mycompany/Django/a6.py
      File "C:/Users/TLCB/PycharmProjects/untitled/mycompany/Django/a6.py", line 7
        f('1','2','aa',x='ff',y='gg',z)
    SyntaxError: non-keyword arg after keyword arg

  • 相关阅读:
    VS2008下编的程序生成的EXE 在没有安装VS2008的计算机上能运行
    GDI+使用小记
    双缓冲技术绘图
    INI文件格式及其读写
    缩放图片并保存
    按值传递&&按引用传递&&按地址传递
    傻瓜式制作的U盘winpe(支持4G以上U盘)速度超快
    vi 命令大全
    fopen和open的区别
    Linux下Socket网络编程,文件传输,数据传输的C语言例子
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13349529.html
Copyright © 2020-2023  润新知