Python:通过名称和kwargs传递参数

Python:通过名称和kwargs传递参数,python,function,arguments,keyword-argument,pass-by-name,Python,Function,Arguments,Keyword Argument,Pass By Name,在python中,我们可以这样做: def myFun1(one = '1', two = '2'): ... def myFun2(**kwargs): print kwargs.get('one', 'nothing here') myFun2(one='one') 然后我们可以调用该函数并按其名称传递参数: myFun1(two = 'two', one = 'one') 此外,我们可以这样做: def myFun1(one = '1', two = '2'):

在python中,我们可以这样做:

def myFun1(one = '1', two = '2'):
    ...
def myFun2(**kwargs):
    print kwargs.get('one', 'nothing here')

myFun2(one='one')
然后我们可以调用该函数并按其名称传递参数:

myFun1(two = 'two', one = 'one')
此外,我们可以这样做:

def myFun1(one = '1', two = '2'):
    ...
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')
一般来说,我们可以做什么组合

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

总体思路是:

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):
    ...
这将允许调用
name
lname
作为关键字

请注意,这是一个不寻常的界面,可能会让用户感到厌烦-我只会在非常特定的用例中使用它

在2.x中,您需要通过解析
**kwargs

手动执行此操作。总体思路是:

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):
    ...
这将允许调用
name
lname
作为关键字

请注意,这是一个不寻常的界面,可能会让用户感到厌烦-我只会在非常特定的用例中使用它


在2.x中,您需要通过解析
**kwargs

手动实现这一点,至少在Python2.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,也会填充插槽)

至少在Python2.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,也会填充插槽)

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

def添加(a=1,b=2,**c):
res=a+b
对于c中的项目:
res=res+c[项目]
打印(res)
添加(2,3)
五,

add(b=4,a=3)
七,

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


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

def添加(a=1,b=2,**c):
res=a+b
对于c中的项目:
res=res+c[项目]
打印(res)
添加(2,3)
五,

add(b=4,a=3)
七,

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


小心。我认为在*args之后不能有默认的args(至少在python2.x上不能)。@mgilson我总是忘记2.x的缺点,在python2.7
def测试(var,kwarg1=1,*args,**kwargs)中修复了:…
对我不起作用。抱怨一个关键字参数有多个值。@Raufio问题在于,你大概是在调用它,按位置和关键字填充
kwarg1
这显然为同一个变量提供了两个值。例如:
test(1,2,kwarg1=3)
,应该
kwarg1
2
还是
3
?要么做
test(1,2)
或者
test(1,kwarg1=3)
@Raufio
test(1,10,1,2,3,test=15)
小心。我认为在*args之后不能有默认的args(至少在python2.x上不能)@mgilson我总是忘记2.x的缺点,在python2.7
def测试(var,kwarg1=1,*args,**kwargs)中修复了这些缺点:…
对我不起作用。抱怨一个关键字参数有多个值。@Raufio这里的问题是你大概在调用它,按位置和关键字填充
kwarg1
,这显然为同一个变量提供了两个值。例如:
test(1,2,kwarg1=3)
,应该