python进阶
1. *args和 **kwargs
*args 和 **kwargs 主要用于函数定义。 你可以将不定数量的参数传递给一个函数。
1.1 *args的用法
*args 是用来发送一个非键值对的可变数量的参数列表给一个函数.
def test_arg(arg, *args):
print(arg);
print(type(args))
print(args)
test_arg(2,2,3,4,5,6)
结果
2
<class 'tuple'>
([2, 3, 4, 5, 6],)
也可以:
a = (3,4,5,6)
test_arg(2,*a)
很显然,传进来的是一个元组
1.2**kwargs的用法
**kwargs 允许你将不定长度的键值对, 作为参数传递给一个函数
def test_args(arg,**kwargs):
print(arg)
print(type(kwargs))
print(kwargs)
dict ={'1':'lisi','2':'jack'}
test_args(3,**dict)
#结果
3
<class 'dict'>
{'1': 'lisi', '2': 'jack'}
1.3 *args和**kwargs一起使用
那么如果你想在函数里同时使用所有这三种参数, 顺序是这样的:
some_func(fargs, *args, **kwargs)
*args必须在 **kwargs前面
如何理解这样传参? 如果要理解参数怎么传递的,一定要先理解 * 和 **的用法
1.4 * 和 ** 的用法
* 和 ** 同时有打包和解包的作用。
1.4.1 解包
* 解包
可以解字符串,元组,列表,集合等类型。
one = 'lisi'
two = (2,3,4,'lis')
three = [3,4,5,'ksf']
third = {3,4,5,'dfs'}
print("one={one}".format(one=one))
print(*one)
print("two={two}".format(two=two))
print(*two)
print("three={three}".format(three=three))
print(*three)
print("thrid={thrid}".format(thrid=third))
print(*third)
#结果
one=lisi
l i s i
two=(2, 3, 4, 'lis')
2 3 4 lis
three=[3, 4, 5, 'ksf']
3 4 5 ksf
thrid={'dfs', 3, 4, 5}
dfs 3 4 5
会将这些容器进行解包处理
1.4.2 ** 解包
**用于解包字典中的键值对
dicts = {'a':3,'b':4,'c':"jack"}
def test_dicts(a,b,c):
print('a:{a},b:{b},c:{c}'.format(a=a,b=b,c=c))
test_dicts(**dicts)
#结果
a:3,b:4,c:jack
很显然,字典的解包是按照键值对进行解包
dicts = {'a':3,'b':4,'c':"jack"}
print(**dicts)
#报错
Traceback (most recent call last):
File "F:/D/pythonProject/pytorchs/advance/arg2.py", line 16, in <module>
print(**dicts)
TypeError: 'a' is an invalid keyword argument for print()
很显然,字典解包需要对应的key值与其对应。
1.4.3 打包
打包的使用常常和函数一起配合使用,就是前面刚刚学习的 * args 和 **kwargs
你肯定会问为什么是打包呢?我从参数的角度给你做个解释,* args表示传入多个参数,当我们正常传参的时候是一个一个进行传参,他的作用就是将多个元素打包为一个元组。同理 **kwargs是将多个键值对元素打包为一个字典。
所以函数传参的时候不要让*args和 **kwargs 迷惑了你,我们给函数传参仍旧是一个一个参数进行传递,然后他进行打包。
举例:
def test(*args):
print(args)
test(2,3,4,5)
tuples =(3,4,5,55,9)
test(*tuples)
可以直接传入多个元素,也可以先定义一个元组使用 * 进行解包,都是可以的。说到这里相信所有的问题都变得很简单了。
函数编写的时候是打包的作用,函数调用的时候是解包的作用