python positional args and keyword args
我正在阅读mercurial的源代码,并在commands.py中找到了这样一个func def:
1 2 | def import_(ui, repo, patch1=None, *patches, **opts): ... |
在python中,positional参数必须放在关键字参数前面。但在这里,
看看PEP 3102,它似乎也与此有关。
总而言之,补丁和opt可以接受变量参数,但后面的接受关键字参数。关键字参数作为字典传递,其中作为变量的位置参数将包装为元组。
从你的例子中
1 | def import_(ui, repo, patch1=None, *patches, **opts): |
另一件重要的事情是,呼叫方有责任确保不违反
因此,违反这一点会导致语法错误。
例如
像呼叫
1 2 3 4 | import_(1,2,3,test="test") import_(1,2,3,4,test="test") import_(1,2,3,4,5) import_(1,2,patch1=3,test="test") |
是有效的,但
1 | import_(1,2,3,patch1=4,5) |
会引起语法错误
在第一个有效案例中,
1 2 | u1=1,repo=2,patch1=3,patches=()and opts="test":"测试<div class="suo-content">[collapse title=""]<ul><li>谢谢你的例子和参考,我想我得到了我的答案。python的参数非常灵活,在这个问题之前我对它的了解还不够。</li></ul>[/collapse]</div><hr><P>可能您有点混淆了函数定义和函数调用语法。</P><P><wyn>patch1</wyn>不是关键字arg,它是一个指定了默认参数值的位置参数。</P><P><wyn>*patches</wyn>是参数列表,而不是位置参数。</P><P>请从官方教程中查看此部分:</P><ul><li>http://docs.python.org/tutorial/controlflow.html关于定义函数的更多信息</li></ul><P>现在让我以这个函数为例总结一下要点:</P>[cc lang="python"]def f1(a1, a2, a3=None, *args, **kwargs): print a1, a2, a3, args, kwargs |
函数定义
您有许多由名称(
可以使用附加参数调用函数,这些参数将出现在字典
在函数定义中,需要先指定不带默认初始值设定项的显式参数,然后指定带默认初始值设定项的显式参数,再指定参数列表,最后指定关键字参数字典。
函数调用
调用函数有多种方法。例如,以下调用是否会产生相同的结果:
1 2 3 | f1(1, 2) # pass a1 and a2 as positional arguments f1(a2=2, a1=1) # pass a1 and a2 as keyword arguments f1(1, a2=2) # pass a1 as positional argument, a2 as keyword argument |
也就是说,函数参数可以通过其位置(位置参数或非关键字参数)或指定的名称(关键字参数)来解析。
调用函数时,需要首先放置非关键字参数,最后放置关键字参数,例如
1 2 3 4 | # demonstrate how some additional positional and keyword arguments are passed f1(1, 2, 3, 4, 5, 6, 7, a4=8, a5=9, a6=10) # prints: # 1 2 3 (4, 5, 6, 7) {'a5': 9, 'a4': 8, 'a6': 10} |
现在,不符合函数定义中指定参数列表的位置参数将附加到参数列表
我相信当调用函数时:
1 | function(arg1="value") |
这将使用"keyword"参数,但在定义函数的接口时:
1 | def function(arg1="value"): |
您正在定义"默认值"。()
因此,为了回答您的问题,在位置参数之后有一个默认值是完全正常的,在关键字之前调用带有非关键字参数的函数也是如此。
还要注意,调用函数时,关键字后不能有非关键字参数。
因为如果关键字参数的位置明确,则将其传递给它是可选的。观察:
1 2 3 4 5 6 7 8 9 10 | >>> def f(ui, patch1=None, *patches, **opts): ... print patch1 ... >>> f(1, 2) 2 >>> f(1, patch1='a', 3) File"<stdin>", line 1 SyntaxError: non-keyword arg after keyword arg >>> f(1, 'a', 3) a |
如您所见,省略
编辑:Moooeeep在他的回答中说
"patch1 is not a keyword arg, it's a positional arg with a default argument value assigned."
这并不是错的,但下面的IMO案例说明了为什么这样的定义是模棱两可的:
1 2 3 4 5 6 7 | >>> def f(ui, p1=None, p2=None, *patches, **opts): ... print p1, p2 ... >>> f(1, 'a', 'b', 3) #p2 is a positional argument with default value? a b >>> f(1, p2='b') #p2 is a keyword argument? None b |
嗯!