Python:按名称和kwargs传递参数

时间:2013-02-25 19:25:53

标签: python function arguments kwargs pass-by-name

在python中我们可以这样做:

def myFun1(one = '1', two = '2'):
    ...

然后我们可以调用函数并按名称传递参数:

myFun1(two = 'two', one = 'one')

另外,我们可以这样做:

def myFun2(**kwargs):
    print kwargs.get('one', 'nothing here')

myFun2(one='one')

所以我想知道是否可以将两种方法结合起来:

def myFun3(name, lname, **other_info):
    ...

myFun3(lname='Someone', name='myName', city='cityName', otherInfo='blah')

一般来说,我们可以做哪些组合?

感谢和抱歉我的愚蠢问题。

3 个答案:

答案 0 :(得分:25)

一般的想法是:

def func(arg1, arg2, ..., kwarg1=default, kwarg2=default, ..., *args, **kwargs):
    ...

您可以根据需要使用尽可能多的人。 ***将“吸收”任何其他未计入的剩余价值。

关键字不能给出位置参数(没有默认值),非默认参数不能遵循默认参数。

注意Python 3还增加了在*之后指定仅限关键字参数的功能:

def func(arg1, arg2, *args, kwonlyarg=default):
    ...

您也可以单独使用*def func(a1, a2, *, kw=d):),这意味着不会捕获任何参数,但之后的任何内容都只是关键字。

所以,如果你在3.x中,你可以产生你想要的行为:

def myFun3(*, name, lname, **other_info):
    ...

允许使用namelname作为关键字进行通话。

请注意,这是一个不寻常的界面,可能会让用户烦恼 - 我只会在非常具体的用例中使用它。

在2.x中,您需要通过解析**kwargs手动进行此操作。

答案 1 :(得分:1)

您可以将命名参数与kwargs一起添加。如果键在调用函数中可用,它将被带到您的命名参数,否则将被kwargs字典带入。

def add(a=1, b=2,**c):
    res = a+b
    for items in c:
        res = res + c[items]
    print(res)
add(2,3)

5

add(b=4, a =3)

7

add(a =1,b=2,c=3,d=4)

10

答案 2 :(得分:0)

至少对于Python 2.7来说这是可能的。关键字参数按名称分配给位置参数,因此您可以执行

In [34]: def func(name, lname, **kwargs):
    print 'name='+name, 'lname='+lname
    print kwargs
   ....:     

In [35]: func(lname='lname_val', name='name_val', city='cityName', otherInfo='blah')
name=name_val lname=lname_val
{'city': 'cityName', 'otherInfo': 'blah'}

官方文档以这种方式说明: "如果存在关键字参数,则首先将它们转换为位置参数,如下所示。首先,为形式参数创建未填充的槽列表。如果有N个位置参数,则将它们放在前N个槽中。接下来,对于每个关键字参数,标识符用于确定相应的槽(如果标识符与第一个形式参数名称相同,则使用第一个槽,依此类推)。如果插槽已填充,则引发TypeError异常。否则,参数的值放在槽中,填充它(即使表达式为None,它填充槽)。" https://docs.python.org/2/reference/expressions.html#calls