Python系列之*args和**kwargs的作用

这篇文章学习了函数中可变参数的两种形式*args**kwargs,主要学习了这两种参数的用法以及在与其他类型的参数联合使用时的顺序问题

简介

*args**kwargs是我在查看源码时经常看到的两个参数,主要出现在各种函数中。这两个参数都是表示给函数传不定数量的参数(不确定最后使用这个函数的时候会传递多少参数,也叫可变参数),两者的差异主要表现在:

  • *args:接收不定量的非关键字参数,如testFun('Hello', 'Welcome')
  • **kwargs:接收不定量个关键字参数,如testFun(x=1, y=2)

*args**kwargs参数关键的是最前面的***,后面的 argskwargs只是约定俗成的叫法而已,也可以使用*vars**kwvars进行代替。


*args

*args可以用于接收不定量的非关键字参数,下面使用几个例子来加深对其的理解.

完全的不定量的非关键字参数(可变参数)

1
2
3
4
5
6
7
8
9
10
11
12
13
def print_func(*args):
print(type(args))
print(args)
for arg in args:
print(arg)

print_func(1, 2, 'str', [])
<class 'tuple'>
(1, 2, 'str', [])
1
2
str
[]

从上面的输出结果可以看出,函数接收的*args会被存放在一个tuple中。

增加普通参数x,y

1
2
3
4
5
6
7
8
9
10
11
12
def print_func(x,y,*args):
print(type(args))
print(args)
for arg in args:
print(arg)

# 这里的1,2分别对应前面的x,y,可变参数只剩下了'str', []
print_func(1, 2, 'str', [])
<class 'tuple'>
('str', [])
str
[]

调整普通参数和可变参数的顺序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def print_func(*args,x,y):
print(type(args))
print(args)
for arg in args:
print(arg)

# 此时会报错
print_func(1, 2, 'str', [])
-
TypeError Traceback (most recent call last)
<ipython-input-224-570961470325> in <module>
5 print(arg)
6
----> 7 print_func(1, 2, 'str', [])

TypeError: print_func() missing 2 required keyword-only arguments: 'x' and 'y'

上面的输出内容表明,可变参数一定要在普通参数之后,如果调换顺序会报错


**kwargs

**kwargs可以用于接收不定量个关键字参数,下面依旧是使用几个例子来进行学习。

1
2
3
4
5
6
7
8
9
10
11
12
13
def print_func(**kwargs):
print(type(kwargs))
print(kwargs)
for kwarg in kwargs.items():
print(kwarg)

print_func(a=1, b=2, c='str', d=[])
<class 'dict'>
{'a': 1, 'b': 2, 'c': 'str', 'd': []}
('a', 1)
('b', 2)
('c', 'str')
('d', [])

从上面的输出结果可以看出:不同于*args传递的参数会被存放在tuple中,**kwargs传递的参数会被存放在字典中。

接下来依旧是顺序问题:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 可变参数在普通参数之后
def print_func(x,y,**kwargs):
print(type(kwargs))
print(kwargs)
for kwarg in kwargs.items():
print(kwarg)

print_func(1, 2, c='str', d=[])
<class 'dict'>
{'c': 'str', 'd': []}
('c', 'str')
('d', [])


# 可变参数在普通参数之前
## 仍旧报错
def print_func(**kwargs,x,y):
print(type(kwargs))
print(kwargs)
for kwarg in kwargs.items():
print(kwarg)

print_func(c='str', d=[],1,2)
File "<ipython-input-235-01d144bf7b9f>", line 1
def print_func(**kwargs,x,y):
^
SyntaxError: invalid syntax

上面的输出内容表明,可变参数一定要在普通参数之后,如果调换顺序会报错


混合使用

目前已经出现了两种参数类型(还有一种是默认参数),前面的示例中也可以看出,普通参数在和可变参数混用时需要注意顺序问题,具体来说:普通参数>默认参数>*args>`kwargs`**.

1
2
3
4
5
6
7
8
9
10
def print_func(x, *args, **kwargs):
print(x)
print(args)
print(kwargs)

# 不同参数类型混用
print_func(1, 2, 3, 4, y=1, a=2, b=3, c=4)
1
(2, 3, 4)
{'y': 1, 'a': 2, 'b': 3, 'c': 4}


参考链接



-----本文结束感谢您的阅读-----

本文标题:Python系列之*args和**kwargs的作用

文章作者:showteeth

发布时间:2020年05月23日 - 11:23

最后更新:2020年05月24日 - 09:42

原始链接:http://showteeth.tech/posts/38814.html

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

0%