python中*args和**kwargs的用法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_37653394/article/details/82595240

args 和 kwargs 不是必须的,* 和 ** 才是必须的

两者都用于对函数进行参数传递,允许传递不定量的参数给函数

1. Overview

如果对各位同学这两个参数知道的很少,那不妨先输出一下,看看他们是什么:

def func(*args, **kwargs):
    print(args)
    print(kwargs)
    print("------------------")

if __name__ == "__main__":
    func()
    func(1, 2, 3, 4)
    func(A = 1, B = 2, C = 3)
    func("python", 123, A = 1, B = 2, C = 3)

输出结果如下:

()
{}
------------------
(1, 2, 3, 4)
{}
------------------
()
{'A': 1, 'B': 2, 'C': 3}
------------------
('python', 123)
{'A': 1, 'B': 2, 'C': 3}
------------------

我们从上面的测试代码中,我们至少可以看到:

  • 在函数内部args是一个tuplekwargs是一个dict、

  • *args**kwargs是可选参数,调用函数时可以输入,也可以不输入

2. Details

先了解一下关于函数参数的几个概念:

参考这篇博客:Python中位置参数、默认参数、可变参数、命名关键字参数、关键字参数的区别

2.1 *args ( Positional Arguments )


 本质上是一个tuple

*args用于接收不定量个位置参数,可以是0个,也可以是任意个。

测试如下:

def test_args(para, *args):
    print("first para == {0}\n".format(para))
    print("args para == {0}".format(args))
    for idx, value in enumerate(args):
        print("para {0} == {1}".format(idx, value))

if __name__ == "__main__":
    test_args("cliffswallow", "hello", "python", 2018)

结果如下:

first para == cliffswallow

args para == ('hello', 'python', 2018)
para 0 == hello
para 1 == python
para 2 == 2018

分析如下:

在上面的测试中,test_args()函数中有两个参数,第一个是必须要输入的参数,第二个是可选参数。在调用该函数时,我们传进去了4个参数,分别是 "cliffswallow", "hello", "python", 2018。第一个参数被当做了必选参数输入,其余三个参数被当做可选参数输入,从输出结果中可以看到,后面三个参数被组装(pack)成为了一个tuple


当多余的参数以tuple,list,set形式出现时,还可以使用 * 对其进行unpack位置参数,然后在函数内部又被packtuple。因此,多余的位置参数在函数内部都是以tuple形式出现的。

看下面:

def test_args(para, *args):
    print("first para == {0}\n".format(para))
    print("args para == {0}".format(args))

if __name__ == "__main__": 
    arg = ("hello", "tuple", 2018)      #1    
    # arg = {"hello", "set", 2018}      #2
    # arg = ["hello", "list", 2018]     #3

    test_args("cliffswallow", *arg)

结果如下:

#1
"""
first para == cliffswallow

args para == ('hello', 'tuple', 2018)
"""

#2
"""
first para == cliffswallow

args para == ('hello', 'set', 2018)
"""

#3
"""
first para == cliffswallow

args para == ('hello', 'list', 2018)
"""

分析如下:

tuple,list,set先被 * unpack成位置参数,然后在函数内部又被packtuple

小结一下:在使用*args的地方,可以直接输入多个位置参数,也可以输入在序列/集合参数的前面加上*符号输入。在函数内部都会被packtuple形式。

2.2 **kwargs ( Keyword Arguments )


本质上是一个dict

**kwargs用于接收0个或者任意个的关键字参数,这里的关键字就是参数名(联想一下默认参数的形式)

测试如下:

def test_kwargs(para, **kwargs):
    print("first para == {0}\n".format(para))
    for key, value in kwargs.items():
        print("{0} == {1}".format(key, value))
if __name__ == "__main__":
    test_kwargs("cliffswallow", python = "py", java = 123, swift = None)

结果如下:

first para == cliffswallow

python == py
java == 123
swift == None

同样地,** 可以将字典unpack成关键字参数

测试如下:

def test_kwargs(**kwargs):
    print(test_paras)
    for key, value in kwargs.items():
        print("{0} == {1}".format(key, value))

if __name__ == "__main__":
    test_paras = {"PYTHON":"python", "JAVA":"java", "hello":123}
    test_kwargs(**test_paras)

结果如下:

{'PYTHON': 'python', 'JAVA': 'java', 'hello': 123}
PYTHON == python
JAVA == java
hello == 123

小结一下:在使用**kwargs的地方,可以直接输入多个关键字参数,也可以通过在dict类型参数前面加 ** 符号输入,**会自动将dict unpack成关键字参数。

2.3 同时使用*args和**kwargs


同时使用*args和**kwargs时,*args需要在**kwargs前面

测试如下:

def func(name, age = 18, *args, **kwargs):
    print(name, age)
    print(args)
    print(kwargs)

if __name__ == "__main__":
    func("cliffswallow", 20, "China", "Beijing", height = 181, weight = 130)

结果如下:

cliffswallow 20
('China', 'Beijing')
{'height': 181, 'weight': 130}

总结一下:在定义的函数参数列表中使用*args**kwargs,则在调用这个函数时,*args表示可以对函数传递不定量的位置参数,这些参数自动在函数内部组装成一个tuple**kwargs则允许对函数传递不定量个关键字参数,他们在函数内部被组装成dictargskwargs不是必须的,只是两个约定俗成的名字,也可以用其他名词代替。在函数调用时,* 可以将序列/集合 unpack成位置参数,** 可以将字典unpack成关键字参数。

猜你喜欢

转载自blog.csdn.net/qq_37653394/article/details/82595240