先来看个例子:
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 = {'a': 1, 'c': 3, 'b': 2}
---------------------------------------
args = (1, 2, 3, 4)
kwargs = {'a': 1, 'c': 3, 'b': 2}
---------------------------------------
args = ('a', 1, None)
kwargs = {'a': 1, 'c': 3, 'b': '2'}
---------------------------------------
可以看到,这两个是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”。
呵呵,知道*args和**kwargs是什么了吧。还有一个很漂亮的用法,就是创建字典:
def kw_dict(**kwargs):
return kwargs
print kw_dict(a=1,b=2,c=3)
>>> {'a':1, 'b':2, 'c':3}
其实python中就带有dict类,使用dict(a=1,b=2,c=3)即可创建一个字典了。
我们也可以使用 zip 来创建字典dict,例如:
a = ["A", "B", "C", "D", "E"]
b = [1, 2, 3, 4, 5]
mydict = dict(list(zip(a, b)))
print(mydict)
1. *args可以当作可容纳多个变量组成的tuple , **kwargs可以当作容纳多个key和value的dict
# 接收不定长参数*args
def fun_var_args(farg, *args):
print "arg:", farg
for value in args:
print "another arg:", value
fun_var_args(1, 2, 3) # *args可以当作可容纳多个变量组成的tuple
<< arg: 1
<< another arg: 2
<< another arg: 3
# 传收不定长参数*args
def fun_var_args_call(arg1, arg2, arg3):
print "arg1:", arg1
print "arg2:", arg2
print "arg3:", arg3
args = [2, 3] #list
fun_var_args_call(1, *args) # *list是为了对arg unpack变成tuple,变成分开的位置参数
<< arg1: 1
<< arg2: 2
<< arg3: 3
# 接收不定长参数**kwargs
def fun_var_kwargs(arg1, **kwargs):
print "arg1:", arg1
for key in kwargs:
print "%s: %s" % (key, kwargs[key])
fun_var_kwargs(arg1=1, arg2=2, arg3=3) # **kwargs可以当作容纳多个key和value的dict
<< arg1: 1
<< arg2: 2
<< arg3: 3
# 传收不定长参数**kwargs
def fun_var_args_call(arg1, arg2, arg3):
print "arg1:", arg1
print "arg2:", arg2
print "arg3:", arg3
kwargs = {"arg3": 3, "arg2": 2} # dictionary
fun_var_args_call(1, **kwargs)
<< arg1: 1
<< arg2: 2
<< arg3: 3
2. 函数定义中的形参中有'*'号的作用,这里只说命名关键字参数
* 后是命名关键字参数,这样就不接受不存在的关键字参数。
命名关键字参数必须传入参数名,这和位置参数不同。如果没有传入参数名,调用将报错。
不过命名关键字参数可通过设置默认值来简化调用。
举个例子说明,或者查看:https://stackoverflow.com/questions/36467057/what-is-the-use-of-in-python-function-definition
def normalize_paf(intensity_fields, j1_fields, j2_fields, j1_fields_logb, j2_fields_logb, *, my_param,
fixed_b=None):
这里的 * 号没有实际形参占位的作用,仅仅用于强制 * 号后面的参数只能是[命名]关键字参数,不能是位置参数,即只能输入fixed_b=a_value,my_param=another_value,且不能输入其他不存在的命名关键字参数 。注意,使用命名关键字参数时,要特别注意,如果没有可变参数(如*arg),就必须加一个*
作为特殊分隔符。如果缺少*
,Python解释器将无法识别位置参数和命名关键字参数,例如
def person(name, age, *, city, job):
# 若缺少 *,city和job被视为位置参数
pass
而如果有可变参数,则不必再加入*作为特殊分隔符,如下例所示,city和job将被当作命名关键字参数。正如之前所说,命名关键字参数必须要传入参数(有默认值的除外),否则将会报错。
def person(name, age, *args, city, job):
print(name, age, args, city, job)
person('Jack', 24, city='Beijing', job='Engineer')
>>>Jack 24 () Beijing Engineer
person('Jack', 24, city='Beijing')
>>> TypeError: person() missing 1 required keyword-only argument: 'job'
单/双星号变量
实际上对一个普通变量使用单星号前缀,能够将这个变量拆分成单个元素。双星号可以用来获得字典的值。
例如
def add(a, b):
return a+b
data = [4,3]
print add(*data)
#equals to print add(4, 3)
data = {'a' : 4, 'b' : 3}
print add(**data)
#equals to print add(4, 3)
转置数组的应用
合并字典的应用
参考:
[1]http://www.cnblogs.com/fengmk2/archive/2008/04/21/1163766.html
[2] https://stackoverflow.com/questions/36467057/what-is-the-use-of-in-python-function-definition
[3] https://blog.csdn.net/xw2017/article/details/88638915