python位置args和关键字args

guo*_*iao 9 python function func

我正在阅读mercurial的源代码,并在commands.py中找到了这样的函数def:

def import_(ui, repo, patch1=None, *patches, **opts):
    ...
Run Code Online (Sandbox Code Playgroud)

在python中,postional args必须放在关键字args之前.但这里patch1是一个关键字参数,后跟一个位置参数*patches.为什么这样好?

Abh*_*jit 9

只是看看PEP 3102也似乎它与有点相关.

总而言之,patch和opts可以接受变量参数,但后者是接受关键字参数.关键字参数作为字典传递,因为变量位置参数将被包装为元组.

从你的例子

def import_(ui, repo, patch1=None, *patches, **opts):
Run Code Online (Sandbox Code Playgroud)

之后的任何位置参数u1,repo and patch1都将被包装为补丁中的元组.变量位置参数后面的任何关键字参数都将通过opts包装为Dictionary对象.

另一个重要的事情是,调用者有责任确保non-keyword arg after keyword arg不违反条件.

所以违反这一点会引发语法错误.

例如

电话就像

 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")
Run Code Online (Sandbox Code Playgroud)

是有效的,但是

import_(1,2,3,patch1=4,5)
Run Code Online (Sandbox Code Playgroud)

会引发语法错误 SyntaxError: non-keyword arg after keyword arg

在第一个有效的情况下 import_(1,2,3,test="test")

u1 = 1, repo = 2, patch1 = 3, patches = () and opts={"test":"test"}
Run Code Online (Sandbox Code Playgroud)

在第二个有效的情况下 import_(1,2,3,patch1=4,test="test")

u1 = 1, repo = 2, patch1 = 3 , patches = (4) and opts={"test":"test"}
Run Code Online (Sandbox Code Playgroud)

在第三个有效的案例中 import_(1,2,3,4,5)

u1 = 1, repo = 2, patch1 = 3 , patches=(4,5), and opts={}
Run Code Online (Sandbox Code Playgroud)

在第四个有效的情况下 import_(1,2,patch1=3,test="test")

u1 = 1, repo = 2, patch1 = 3 , patches=(), and opts={"test":"test"}
you can use patch1 as a keywords argument but doing so you cannot wrap any variable positional arguments within patches
Run Code Online (Sandbox Code Playgroud)