• python中函数调用、定义时星号的含义(*列表,**字典)& python中的*args和**kw


    ########转自 caixxiong:https://me.csdn.net/qq_24406903#########

    调用函数时使用:*、**
        test(*args)中 * 的作用:其实就是把序列 args 中的每个元素,当作位置参数传进去。比如上面这个代码,如果 args 等于 (1,2,3) ,那么这个代码就等价于 test(1, 2, 3) 。
        test(**kwargs)中** 的作用:则是把字典 kwargs 变成关键字参数传递。比如上面这个代码,如果 kwargs 等于 {'a':1,'b':2,'c':3} ,那这个代码就等价于 test(a=1,b=2,c=3) 。

    定义函数参数时使用* 、**
    def test(*args):
         这里 *args 表示把传进来的位置参数都装在元组 args 里面。比如说上面这个函数,调用 test(1, 2, 3) 的话, args 的值就是 (1, 2, 3) 。

    def test(**kwargs):
        类似的, ** 就是针对关键字参数和字典的了,调用 test(a=1,b=2,c=3) 的话, kwargs 的值就是 {'a':1,'b':2,'c':3} 了。

    "普通的参数定义和传递方式和 * 们都可以和平共处,不过显然 * 必须放在所有位置参数的最后,而 ** 则必须放在所有关键字参数的最后,否则就要产生歧义了。"

    上面用引号括起来的话是摘抄作者的原文,但是我做了下实验,发现在调用时,*不一定要在位置参数后面,它可以在任意位置,只要传递参数不冲突,但是**的位置则有一定要求了,因为它必须按照关键字参数的要求传递,但是关键字参数和**的位置是可以随意的.

     1 def fun(a,b,c,d,e,f,g,h,i,j):
     2     print(a,b,c,d,e,f,g,h,i,j)
     3     return
     4 L = [8,8,8,8,8]
     5 fun(1,2,3,*L,4,5)          # 1 2 3 8 8 8 8 8 4 5
     6 fun(1,2,3,*L,i=4,j=5)   # 1 2 3 8 8 8 8 8 4 5
     7 fun(1,2,3,i=4,j=5,*L)    # 1 2 3 8 8 8 8 8 4 5
     8 fun(*L,1,2,3,i=4,j=5)   # 8 8 8 8 8 1 2 3 4 5
     9 
    10 D = {'d':1,'f':2,'e':3} 
    11 fun(8,8,8,**D,g=10,h=10,j=10,i=10) # 8 8 8 1 3 2 10 10 10 10
    12 fun(8,8,8,g=10,h=10,j=10,i=10,**D) # 8 8 8 1 3 2 10 10 10 10

    在定义函数时: *和**参数均最多有一个,**参数如果有则必须是最后一个参数,默认位置参数必须在非默认位置参数之后,而*参数则可以穿插在默认和非默认参数之间均可.

    函数定义时的各类参数顺序分析
    如果不考虑*参数,则参数列表只能是:(p1,p2,d1=0,d2=0,**k),其中p,d代表非默认位置参数和默认位置参数.
    考虑加上参数,则有以下几种可能
    (,p1,p2,d1=0,d2=0,**k),此时四个位置参数p1,p2,d1,d2必须都作为位置参数传入,当然d1,d2可以不传
    (p1,*l,p2,d1=0,d2=0,**k),此时p2,d1,d2必须用位置实参传递
    (p1,p2,*l,d1=0,d2=0,**k),此时d1,d2需用位置实参传递
    (p1,p2,d1=0,*l,d2=0,**k),此时d2需要用位置实参传递
    (p1,p2,d1=0,d2=0,*l,**k),此时位置参数按顺序给p1,p2,d1,d2,有剩余的则给l

     1 def f(*l,p1,p2,d1=0,d2=0,**k): 
     2     print(l,p1,p2,d1,d2,k) 
     3 
     4 f(1,2,3,p1=4,p2=5,d1=6,d2=7,kk=100) # (1, 2, 3) 4 5 6 7 {'kk': 100}
     5 
     6 def f(p1,*l,p2,d1=0,d2=0,**k): 
     7     print(p1,l,p2,d1,d2,k) 
     8 f(1,2,3,p2=4,d1=5,d2=6,kk=100) # 1 (2, 3) 4 5 6 {'kk': 100}
     9 
    10 def f(p1,p2,*l,d1=0,d2=0,**k): 
    11     print(p1,p2,l,d1,d2,k) 
    12 f(1,2,3,4,d1=5,d2=6,kk=100) # 1 2 (3, 4) 5 6 {'kk': 100}
    13 
    14 def f(p1,p2,d1=0,*l,d2=0,**k): 
    15     print(p1,p2,d1,l,d2,k) 
    16 f(1,2,3,4,5,d2=6,kk=100)  # 1 2 3 (4, 5) 6 {'kk': 100}
    17 f(1,d1=2,p2=3,d2=6,kk=100) # 1 3 2 () 6 {'kk': 100}
    18 
    19 def f(p1,p2,d1=0,d2=0,*l,**k): 
    20     print(p1,p2,d1,d2,l,k) 
    21 f(1,2,3,4,kk=100) # 1 2 3 4 () {'kk': 100}
    22 f(1,2,3,4,5,kk=100) # 1 2 3 4 (5,) {'kk': 100}

    以上实例说明,*参数后的所有位置参数(默认和非默认)必须一关键字实参形式传递,实际上解释器也把它们定义为keyword-only参数了.

    
    

    实际使用中,很少会搞这么复杂,如果硬是要所有四种参数都有,则(p,*l,d=0,**k)和(p,d=0,l,**k)这两种是最清晰的,并且这两种中第一种可能更好用,因为可以同时利用好和默认参数的特性,第二种则不能同时有两种特性.

    python中的*args和**kw

    
    

    学习python装饰器decorator的时候遇到*args和**kw两种函数值传递。

    在python中定义函数,可以使用一般参数、默认参数、非关键字参数和关键字参数。

    一般参数和默认参数在前面的学习中我们都遇到过了,而*args和**kw分别属于非关键字参数和关键字参数,后两者也都是可变参数。

    非关键字参数的特征是一个星号*加上参数名,比如*number,定义后,number可以接收任意数量的参数,并将它们储存在一个tuple中。

    关键字参数的特征是两个星号**加上参数名,比如**kw, 定义后,kw将接收到的任意数量参数存到一个dict中。关键字参数是在传递构成中不必按照顺序传递(因为dict内的key-value是没有顺序的),但必须要提供”传递参数名=传递参数值”形式的参数。

    如:

    def try_it(*args, **kw): 
        print 'args:',args 
        print 'kw:',kw 
    
    try_it(1,2,3,4, a=1,b=2,c=3)
    try_it('a', 1, None, a=1, b='2', c=3)

    运行结果:

    args: (1, 2, 3, 4) 
    kw: {'a': 1, 'c': 3, 'b': 2} 
    
    args: ('a', 1, None) 
    kw: {'a': 1,'b': '2','c': 3, }
    python中的一般参数、默认参数、非关键字参数和关键字参数可以一起使用,或者只用其中某些,但是请注意,参数定义的顺序必须是:一般参数、默认参数、可变参数和关键字参数,先后顺序不能颠倒。即:
    def func(a, b, c=0, *args, **kw):
        pass
  • 相关阅读:
    php之异常处理
    php7之严格模式RFC
    获取真实ip三个方法
    php网站速度性能优化(转)
    PHPweb应用攻击总结(转)
    PHP安全之Web攻击(转)
    php获取真实ip地址(转)
    单表查询
    表与表之间的关系
    表的操作
  • 原文地址:https://www.cnblogs.com/danniel-gong/p/12455924.html
Copyright © 2020-2023  润新知