python中的魔法参数:*args和**kwargs

python中的魔法参数:*args和**kwargs
谢小玲
谢小玲
公众号:python爱好部落
2 人赞同了该文章
在写函数的时候,经常要写形参,我们经常看到*args和**kwargs, 这到底是什么,怎么用呢?
在Java中,有个定义是重载: 函数名可以相同,参数个数不同,或者类型不同,是不同的方法(函数),有的时候参数不同,要写好几个同名的函数。

python似乎做了一些改进,就是用魔法参数:*args和**kwargs。 管你多少个参数,管你什么类型,我都可以扔到这两个里面。这就减少了重复写同名函数。
*args和**kwargs,以及单独的∗,∗∗到底是啥作用呢?
*args有两部分构成为——∗和args。这里的重点是∗。
所以为了讲清楚*args,我们要追根溯源——理解∗的作用。
*的作用—— 打包参数(pack)和拆分参数(unpack)!
打包参数(pack)
例1:

def foo(*number):
    print(number)
    print(type(number))
foo(1, 2, 3, 4, 5)
结果:

(1, 2, 3, 4, 5)
<class 'tuple'>
给函数5个参数,成功运行了,而且输出是参数构成的元组。
我们知道,如果number前不加∗∗号,那么很明显foo()只能接受1个参数,参数给多了少了都要报错。而加上∗∗,就能成功运行。
∗把函数foo()接受到的多个参数1,2,3,4,5,打包成了元组(1,2,3,4,5),赋值给了形参number。
例2:

def foo2(a,*number):
    print("a:{}".format(a))
    print("number:{}".format(number))
    print(type(number))

foo2(1, 2, 3, 4, 5)
结果:

a:1number:(2, 3, 4, 5)
<class 'tuple'>
从例中可以看出,number接受到的实参变成了(2,3,4,5),第一个参数1被形参a接受走了。
∗的作用:函数接受实参时,按顺序分配给函数形参,如果遇到带∗∗的形参,那么就把还未分配出去的实参以元组形式打包(pack),分配给那个带∗的形参。

拆分参数(unpack)

def foo3(a,b,c):
    print(a,b,c)

foo3(*[1,2,3])
把打包了的实参(元组或列表),拆分(unpack)成单个的,依次赋值给函数的形参。
在本例中,打包了的实参[1,2,3]被拆分,1赋值给了形参a,2赋值给了形参b,3复制给了形参c。
注意: 形参个数必须跟列表长度一样,不然就有实参没有接受的形参。

**kwargs
打包(pack):args是把多个位置参数打包成元组,kwargs是把多个关键字参数打包成字典。
拆分(unpack):args是把打包了的参数拆成单个的,依次赋值给函数的形参,**kwargs是把字典的键值拆成单个的,依次赋值给函数的形参。

Pack

def bar(**number):
    print(number)
bar(a=1, b=2, c=3)
结果:

{'b': 2, 'c': 3, 'a': 1}
(unpack)

def bar(a, b, c):
    print(a,b,c)
bar(**{'a': 1, 'b': 2, 'c': 3})
结果:

1 2 3
就是用∗∗方式拆解字典给形参赋值时,需要字典的键名和函数形参一直,否则会报错。

混用
当要同时使用*args和**kwargs时,*args必须写在**kwargs之前。
我们来看例子:

def foo(*args, **kwargs):
    print ('args = ', args)    print ('kwargs = ', kwargs)    print ('---------------------------------------')if __name__ == '__main__':
    foo(1 ,2 ,3 ,4)
foo(a=1 ,b=2 ,c=3)
foo(1 ,2 ,3 ,4, a=1 ,b=2 ,c=3)
foo('a', 1, None, a=1, b='2', c=3)
我们来看结果:

args =  (1, 2, 3, 4)
kwargs =  {}
---------------------------------------
args =  ()
kwargs =  {'b': 2, 'c': 3, 'a': 1}
---------------------------------------
args =  (1, 2, 3, 4)
kwargs =  {'b': 2, 'c': 3, 'a': 1}
---------------------------------------
args =  ('a', 1, None)
kwargs =  {'b': '2', 'c': 3, 'a': 1}
---------------------------------------
可以看到,这两个是python中的可变参数。*args表示任何多个无名参数,它是一个tuple**kwargs表示关键字参数,它是一个 dict。并且同时使用*args和**kwargs时,必须args参数列要在**kwargs前,像foo(a=1, b=2, c=3, a’, 1, None, )这样调用的话,会提示语法错误“SyntaxError: non-keyword arg after keyword arg”。

所以python里面就没有重载,只需要写一个方法,加上魔法参数,就万事大吉。

更多精彩,请关注微信公众号: python爱好部落

发布于 2018-11-30
Python
自动化测试
https://zhuanlan.zhihu.com/p/51236818?from=timeline&isappinstalled=0&utm_source=wechat_session&utm_medium=social&s_s_i=uspDABEc7OiYLPEvjXtY9xOaFExw3Vk%2FolY7T6x4byc%3D&s_r=1
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值