美文网首页Python
Python中的 *args 和 **kwargs

Python中的 *args 和 **kwargs

作者: 西北小生_ | 来源:发表于2020-08-05 21:29 被阅读0次

    1.args 和 kwargs的含义

    *args 和 **kwargs经常出现在函数定义中,如:

    def fun(*args, **kwargs):
         pass
    

    其中args是参数的英文arguments的缩写,在这里表示位置参数(position arguments)。
    kwargs是英文keyword arguments的缩写,即关键字参数

    2.什么是位置参数和关键字参数?

    # 函数定义
    def fun(a, b, c=0, d=1):
        pass
    
    # 函数使用
    # (1)位置参数
    fun(1, 2, 3, 4)
    
    # (2)关键字参数
    fun(b=2, c=3, a=1, d=4)
    
    # (3)位置参数和关键字参数混合
    fun(1, 2, d=5)
    

    在使用函数时,我们需要进行参数传递,这时有三种情况:
    (1)按参数定义时的位置顺序依次进行传递,如 fun(1,2,3,4),此时a=1, b=2, c=3, d=4。
    (2)按参数名(关键字)对其赋值进行参数传递,如 fun(a=1,d=4,c=3,b=2).
    (3)位置和关键字混合传递,如 fun(1,2,d=4),这里的1,2就是位置参数,d=4就是关键字参数。

    3.*args 和 **kwargs:

    函数中同时出现*args 和 *kwargs时,args 位置必须在 **kwargs前面,这是Python语法规定的位置参数必须在关键字参数前面。

    # 定义函数
    In [24]: def fun(*args, **kwargs): 
        ...:     print('args:', args) 
        ...:     print('kwargs:', kwargs) 
        ...:                                                                        
    
    # 使用函数
    In [25]: fun(1,2,3,d=4,e=5)                                                     
    args: (1, 2, 3)
    kwargs: {'d': 4, 'e': 5}
    
    
    从上例中可以看出:*args将会接收函数传入的位置参数,并将其装进一个元组里面赋值给变量args, **kwargs将会接收函数传入的关键字参数,并将其装进一个字典里赋值给变量kwargs。

    4.这里的*和**是什么操作?

    先上结论:

    在声明时,*是对元组或列表的打包操作,将传入的一个或多个值打包成一个元组或列表,并赋值给符号*后面的变量。
    在使用时,*是对元组或列表的拆包操作,将符号*后面的元组或列表拆分成多个元素。
    同样的,**是对字典的相应打包和拆包操作。

    如下例:

    打包:

    In [28]: (a,b,*c)=1,2,3,4,5,6                                                
    
    In [29]: print(a,b,c)                                                        
    1 2 [3, 4, 5, 6]
    
    

    在上例中,第一句表示将括号右边的第一个数赋值给变量a, 第二个数赋值给变量b,后面无论有多少个数,都赋值给变量c。这里的a,b,c均是首次在程序中出现,表示变量的声明和初始化。而变量c前面加了一个*号表示c是一个列表或元组,这样就可以装下多个值。
    在第二行我们输出3个变量a,b,c,可以看出,变量c确实是个列表,它将第三个数及其后面的所有值都打包成一个列表,赋值给了c.

    拆包:

    In [35]: def fun(a,b,c,d): 
        ...:     print(a,b,c,d) 
        ...:                                                                        
    
    In [36]: inp = [1,2,3,4]                                                        
    
    In [37]: fun(inp)                                                               
    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    <ipython-input-37-e8e9c29393b7> in <module>
    ----> 1 fun(inp)
    
    TypeError: fun() missing 3 required positional arguments: 'b', 'c', and 'd'
    
    In [38]: fun(*inp)                                                              
    1 2 3 4
    
    

    上例中我们定义的函数fun需要4个参数,inp是一个包含4个元素的列表,如果直接将这个列表传递给函数fun ,会出现报错。但是如果在其前面加上一个*号就不报错了,这是为什么呢?
    这里的“*”是拆包操作,它作用在一个列表或元组变量前面,表示将其拆分成一个个元素。 即*[1,2,3,4] = 1,2,3,4 相当于“*”作用在一个列表或元组前,可以去除其两边的括号。
    如何区分什么时候是打包,什么时候是拆包呢?

    如果一个变量首次出现,在其前面加了*或 **, 就表示是打包操作,符号*仅仅表示其后面的变量是一个列表或元组变量,可以装任意多个元素值。**表示其后面的变量是一个字典变量,可以装任意多个键值对。
    如果已知一个变量是一个列表,元组或字典,在其前面加上*或 **就表示拆包操作,相当于将其两边的括号去掉。

    同理,**是对字典的打包和拆包。

    相关文章

      网友评论

        本文标题:Python中的 *args 和 **kwargs

        本文链接:https://www.haomeiwen.com/subject/swflrktx.html