学习地址:https://blog.youkuaiyun.com/cadi2011/article/details/84871401
说明: 在python中 *参数(*args) 与 **参数(**kwargs) 被称为可变参数(任意参数)
定义方法时:
*args 收集所有不匹配的位置参数组成一个tuple对象,局部变量名args指向此tuple对象;
**kwargs 收集所有不匹配的位置参数组成一个dict对象,局部变量kwargs指向此dict对象;
举例说明:
定义方法中,参数名称前有一个*
#!/usr/bin/env python
# -*- coding:utf-8 -*-
def print_str(first, *second):
print(first)
print(second)
print('------------------')
if __name__ == "__main__":
my_tuple = ("wang","yuan","wai")
print_str("hello")
print_str("hello", "world")
print_str("hello", my_tuple)
print_str(my_tuple)
print_str(*my_tuple)
输出结果:
hello
()
------------------
hello
('world',)
------------------
hello
(('wang', 'yuan', 'wai'),)
------------------
('wang', 'yuan', 'wai')
()
------------------
wang
('yuan', 'wai')
------------------
说明1:方法调用时传入的参数,会按照从左到右的顺序依次在方法中使用,最左侧的参数先由位置参数first使用,剩下的所有未使用的参数则在print_str方法的内部,被自动收集到1个新的tuple对象中,而局部变量second指向的是新的这个tuple对象。
print_str(*my_tuple)
等同于
print_str("wang","yuan","wai")
说明2:my_tuple自身是一个tuple对象,*my_tuple在方法调用时称为解包(一个“*”字符后面紧挨着1个tuple对象),也称为元组的解包,tuple中的元素解包成一个一个的位置参数传入到函数中
numbers_strings = ("1","2")
def print_str(first, second):
print first
print second
if __name__ == "__main__":
print_str(*numbers_strings)
输出结果:
1
2
print_str(*numbers_string)
等同于
print_str("1","2")
元组解包的过程中会将每一个元素依次放入到位置参数,这说明元组的解包功能:
1、可以在可变参数中使用
2、也可以在只有位置参数的方法中使用
解包功能是完全独立的一个功能
说明:*参数,出现在不同的位置上具备不同的功能。当*参数出现在定义方法时,表示可变参数(元组参数),而当*参数出现在方法调用时,则表示解包功能。
注意:解包tuple的时候,tuple的元素数量要与函数的位置参数总数一致
定义方法中,参数名称前有两个**
def printStr(first, **dict):
print(str(first) + "\n")
print(dict)
if __name__ == '__main__':
printDic = {"name": "tyson", "age":"99"}
printStr(100,**printDic)
printStr(100, **printDic)
#等同于
printStr(100, name = "tyson", age = "99")
说明:在调用方法时,如果参数有匹配的位置参数,则位置参数优先使用这些参数,剩余所有未使用的参数会在方法内组装成一个dict对象,组装后dict对象会赋值给变量名anything,此时局部变量anything指向一个dict对象
注意:**参数只收集未匹配的参数
调用方法时,在一个dict对象的前面,添加**,表示字典的解包,它会把dict对象中的每个键值对元素,依次转换为一个一个的参数传入到方法中
总结
Python语法中,当*和**符号同时出现在定义方法的参数列表中时,说明参数列表可接受任意数量的参数,它们俩都统称为可变参数
定义方法时,*second表示任意个(包含0个)位置参数,每当调用方法时,所有未使用的参数会在方法中自动组装成一个tuple对象,此tuple对象会赋值给变量名second
定义方法时,**anything表示任意个(包含0个)关键字参数,每当调用方法时,所有未使用的关键字参数会在方法内组装成一个dict对象,此dict对象会赋值给变量名anything
注意:二者同时存在时,一定需要将*second放在**anything之前