简单来说,当你传入的参数不能确定是几个的时候会用到 *args和**kwargs,这里星号后边只是个代号,你写成a也可以。
而这两者的区别是 如果是键值对就要用后者,反之前者就可以。
同时还可以用(a, *args, **kwargs)这种方式
具体例子见下面代码:
In [1]: def h(a): ...: print a ...: In [2]: h(3) 3 In [3]: def h(*args): ...: for i in args: ...: print i ...: In [4]: h((1, 2, 3)) (1, 2, 3) In [5]: a = [1, 2, 3] In [6]: h(a) [1, 2, 3] In [7]: h(3) 3 In [8]: h(3, 3) 3 3 In [9]: h(3, 5) 3 5 In [10]: def h(a, *args): ....: print a ....: for i in args: ....: print i ....: In [11]: h(3, 4, 5) 3 4 5 In [12]: h(3, a) 3 [1, 2, 3] In [13]: h(3, (1, 2, 3)) 3 (1, 2, 3) In [14]: h(a) [1, 2, 3] In [15]: h(a, a) [1, 2, 3] [1, 2, 3] In [16]: def h(a): ....: for i in a: ....: print i ....: In [17]: h(a) 1 2 3
In [19]: def h(a, *args): print 'a', a for i in args: print i ....: In [20]: h(1, 3, 4) a 1 3 4 In [21]: h(1, a) a 1 [1, 2, 3] In [22]: h(1, (1, (2, 3))) a 1 (1, (2, 3)) In [23]: h(1, (1, 2, 3)) a 1 (1, 2, 3) In [24]: h(1, (1, 2, 3), (3, 4)) a 1 (1, 2, 3) (3, 4)
注意: 此处并没有正确的打印出结果,小括号里的数并没有按行打出,而是直接打出了,正确的用法是要加上*才可以,见下面的代码
**kwargs的用法:
In [25]: def h(**kwargs): ....: for k, v in kwargs.items(): ....: print k, v ....: In [26]: h({'a': 1, 'b': 3}) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-26-557f772fd853> in <module>() ----> 1 h({'a': 1, 'b': 3}) # 此处没有**,提示错误 TypeError: h() takes exactly 0 arguments (1 given) In [27]: h(**{'a': 1, 'b': 3}) a 1 b 3 In [28]: def hh(*args): ....: for i in args: ....: print i ....: In [29]: hh(*(1, 2, 3)) # 此处是正确的使用方法 1 2 3 In [30]: a = (1, 2, 3) In [31]: hh(*a) 1 2 3 In [32]: def hhh(a, *args): ....: print a, 'a' ....: for i in args: ....: print i ....: In [33]: hhh(*(1, 3, 4)) 1 a 3 4
同时使用三种方式的顺序是, def f(a, *args, **kwargs)
In [34]: def hhhh(a, *args, **kwargs): ....: print 'a:', a ....: for i in args: ....: print i ....: print 'kwargs:' ....: for k, v in kwargs: ....: print k, v ....: In [35]: hhhh(1, *(2, 3), **{'c': 1, 'b': 3}) a: 1 2 3 kwargs: --------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-35-6ac13cc71458> in <module>() ----> 1 hhhh(1, *(2, 3), **{'c': 1, 'b': 3}) <ipython-input-34-18188bbea105> in hhhh(a, *args, **kwargs) 4 print i 5 print 'kwargs:' ----> 6 for k, v in kwargs: 7 print k, v 8 ValueError: need more than 1 value to unpack In [36]: def hhhh(a, *args, **kwargs): print 'a:', a for i in args: print i print 'kwargs:' for k, v in kwargs.items: print k, v ....: In [37]: hhhh(1, *(2, 3), **{'c': 1, 'b': 3}) a: 1 2 3 kwargs: --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-37-6ac13cc71458> in <module>() ----> 1 hhhh(1, *(2, 3), **{'c': 1, 'b': 3}) <ipython-input-36-0e0a773cdf48> in hhhh(a, *args, **kwargs) 4 print i 5 print 'kwargs:' ----> 6 for k, v in kwargs.items: 7 print k, v 8 TypeError: 'builtin_function_or_method' object is not iterable In [38]: def hhhh(a, *args, **kwargs): print 'a:', a for i in args: print i print 'kwargs:' for k, v in kwargs.items(): print k, v ....: In [39]: hhhh(1, *(2, 3), **{'c': 1, 'b': 3}) a: 1 2 3 kwargs: c 1 b 3
注意:items处要加()
参考见:
https://eastlakeside.gitbooks.io/interpy-zh/content/args_kwargs/When_to_use.html
https://docs.python.org/2/tutorial/controlflow.html#defining-functions