Python中的 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 =  {'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

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值