python 参数之 *和**的使用
我们先来看看普通的传值:
1 >普通传值
def myfun(a, b, c, d, e, f, g):
print(a, b, c, g)
myfun(1, 2, 3, 4, 5, 6, 7)
试想一下,万一形参里面有十几个参数,我们是不是得记下参数的位置,并且一一赋值,
而且我要是不想传那么多值,要么用默认值参数,要么等着报错吧。
一个*的作用:
我们可以用语法糖来实现快速赋值,
(语法糖:写代码像吃了糖一样的快乐~~~~内心毫无波动)
2 > 语法糖 之 *星号的作用
(1)打包参数 - 定义函数时,使用*arg可以传入多个参数,会将多个值打包成一个元组处理
(2)解包参数 - 调用函数时(或函数内部处理时),*arg 能够将元组或者列表解包成不同的参数(用于字典时只能对键起作用)
* 号 和 **号都有打包和解包的作用
def myfun(*arg): # 打包参数:形参里面的*号代表可以接收任何数量的实参,使用*arg可以传入多个参数,并且处理时,会将多个值转成一个元组处理
print('没解包:', arg, type(arg))
print('解包:', *arg) # 解包参数:这里的这个*号代表解包,接收到的arg必须是一个可以迭代的数据类型
print('~' * 50)
print('一组 - 传入列表:')
list1 = ['1', 2, '3']
myfun(list1) # 传入 ['1', 2, '3']
myfun(*list1) # 传入1,2,3 解包参数:这里的这个*号代表解包,需要一个可以迭代的实参
##解释:把list1分解成'1',2,'3'后,位置对应的传给形参,等价于调用 myfun(list1[0],list1[1],list1[2])
print('二组 - 传入元组:')
toupe = (4, 5, 6)
myfun(toupe)
myfun(*toupe) # 解包参数:在函数调用中,* 能够将元组或者列表解包成不同的参数
print('三组 - 传入字典 :')
dict1 = {'a': 1, 'b': 2}
myfun(dict1)
myfun(*dict1) # 解包参数:如果是字典的话,只能把键打包成元组传给形参
print('四组:')
myfun(1, 2, 2, 2, 3, 4, 54, 5, 5, 5, 55) # 把这一组值传给形参时,会被打包成元组
myfun() # 传入空值,得到空元组
运行效果:
3 >使用语法糖传值 - 打包参数,即形参*号的几种情况
情况1:
def myfun1(arg1, arg2): # 情况1 没带*号
print(arg1, type(arg1))
print(arg2)
print('~' * 50)
a = (1, 'q')
myfun(a, 'r') # a 传给 arg1,'r' 传给 arg2
myfun(*a) # 这里的这个*号代表解包,需要一个可以迭代的实参:把a分解成1,'q'后,位置对应的传给形参, 1 传给 arg1,'q' 传给 arg2
运行效果:
情况2:
def myfun2(arg1, *arg2): # 情况2 后面带1个*号
print('第1个参数:', arg1, ' 第2个参数:', arg2)
print('~' * 50)
a = (1, 'q')
myfun(a, 'r') # 相当于把a传给arg1,'r'传给arg2
myfun(*a, 99) # 先把a解包,然后把 1,'q',99 当做实参传给形参,1传给arg1,('q',99)传给arg2
运行效果:
注意:带*号的形参必须要放在不带*号的形参之后。如下代码则报错:
def myfun(*arg1, arg2): # 情况3:语法错误,带*号的形参必须要放在不带*号的形参之后
print('第1个参数:', arg1, ' 第2个参数:', arg2)
print('~' * 50)
#myfun('ww', 'qq') # 报错
**的作用:
1、**的用法1 - 打包参数
作用1 :打包参数 - 定义函数时,使用**kwargs可以将关键字传参保存成一个字典传递给函数。
def myFun1(**kwargs): # ** 的作用1:将关键字传参保存成一个字典传递给函数
print(kwargs)
myFun1() #可以跟空的实参,得到空字典
myFun1(a=1, b=2)
运行效果:
解释:
可以看出, ** 代表了给函数传入参数的方式是:a = 1形式,
即:参数名 = 参数值,(只能用等号哦),并且不管传入几个值,该函数都会转化为字典来处理。
注意:如下方式传参会报错
data = {"a": 1, "b": 2}
myFun1(data) # 报错:这种调用data的方法会报错.
2> ** 号的用法2 - 解包参数:
解包参数 - 调用函数时,使用**kwargs 会以键/值的形式解包一个字典,使其成为独立的关键字参数.
实参:必须是一个映射(Mapping),即只能是字典。
扩展:映射(Mapping)
通过名字来引用值的数据结构称为映射,Python中有一种标准映射类型,就是字典(dict)。
def myFun2(a, b, c, d):
print(a, b, c, d)
kwargs = {"a": 1, "b": 2, "c": 3, "d": 4}
a = [1,2,3,4]
myFun2(**kwargs)# 解释:把kwargs按键/值的形式解包,并取字典的值,得到1 2 3 4,再按位置传给对应的形参a,b,c,d
运行效果:
3> **的作用 - 解包参数
def myFun3(**kwargs): # 打包成字典
print(kwargs)
kwargs = {"a": 1, "b": 2, "c": 3, "d": 4}
myFun3(**kwargs) # 解包字典 结果:{'a': 1, 'b': 2, 'c': 3, 'd': 4}
运行结果:
注意:
如果同时使用 *args 和 **kwargs 时,必须*args 参数列要在 **kwargs 之前。
def myFun(*args, **kwargs): ##def (**kwargs,*args): #报错:**kwargs必须放在*args的后面
print(args)
print(kwargs)
print('~'*50)
myFun('huahua', 18, 'xiaohong', job='软件测试', hobby='girl' )
'''解释:
'huahua', 18, 'xiaohong' 传给了*args
job='软件测试', hobby='girl' 传给了**kwargs
'''
d = {'a': 1, 'b': 2, 'c': 3}
myFun(*d) # 把'a', 'b', 'c' 传给args
myFun(**d) # 把 {'a': 1, 'b': 2, 'c': 3} 传给 kwargs
运行效果: