python 位置参数和关键字参数

发布于 2024-12-21 01:42:55 字数 249 浏览 0 评论 0原文

我正在阅读mercurial的源代码,在commands.py中发现了这样一个func def:

def import_(ui, repo, patch1=None, *patches, **opts):
    ...

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

I am reading the source codes of mercurial, and found such a func def in commands.py:

def import_(ui, repo, patch1=None, *patches, **opts):
    ...

in python, postional args must be put ahead of keyword args. But here, patch1 is a keyword argument, followed by a positional argument *patches. why is this OK?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

逆光下的微笑 2024-12-28 01:42:55

只要看看 PEP 3102 也似乎它与这个

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

从您的示例中,

def import_(ui, repo, patch1=None, *patches, **opts):

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

另一件重要的事情是,调用者有责任确保不违反关键字 arg 之后非关键字 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")

是有效的,但

import_(1,2,3,patch1=4,5)

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

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

u1 = 1, repo = 2, patch1 = 3, patches = () and opts={"test":"test"}

在第二个有效案例中 import_(1,2,3,patch1=4,test="test")

u1 = 1, repo = 2, patch1 = 3 , patches = (4) and opts={"test":"test"}

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

u1 = 1, repo = 2, patch1 = 3 , patches=(4,5), and opts={}

在第四个有效案例中 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

Just have a look into the PEP 3102 also it seems its somehow related to this.

To summarize, patches and opts are there to accept variable arguments but the later is to accept keyword arguments. The keyword arguments are passed as a dictionary where as the variable positional arguments would be wrapped as tuples .

From your example

def import_(ui, repo, patch1=None, *patches, **opts):

Any positional parameters after u1,repo and patch1 would be wrapped as tuples in patches. Any keyword arguments following the variable positional arguments would be wrapped as Dictionary objects through opts.

Another important thing is that, the onus lies with the caller to ensure that the condition non-keyword arg after keyword arg is not violated.

So something that violates this would raise a syntax error..

For example

Calls like

 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")

are valid, but

import_(1,2,3,patch1=4,5)

would raise a syntax error SyntaxError: non-keyword arg after keyword arg

In the first valid case import_(1,2,3,test="test")

u1 = 1, repo = 2, patch1 = 3, patches = () and opts={"test":"test"}

In the second valid case import_(1,2,3,patch1=4,test="test")

u1 = 1, repo = 2, patch1 = 3 , patches = (4) and opts={"test":"test"}

In the third valid case import_(1,2,3,4,5)

u1 = 1, repo = 2, patch1 = 3 , patches=(4,5), and opts={}

In the fourth valid case 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
谜泪 2024-12-28 01:42:55

您可能有点混淆函数定义和函数调用语法。

patch1 不是关键字参数,它是分配了默认参数值的位置参数。

*patches 是参数列表,而不是位置参数。


请查看官方教程中的此部分:

现在让我以这个函数为例总结一下要点:

def f1(a1, a2, a3=None, *args, **kwargs):
  print a1, a2, a3, args, kwargs

函数定义

你有一个由显式定义的参数数量名称(a1a2a3),其中 a3 将默认由 None< 初始化/code> 如果在调用期间未提供。需要在该函数的任何有效调用中提供参数 a1a2

该函数可以使用额外的参数来调用,这些参数将出现在字典kwargs(当由关键字提供时)或列表args(当不由关键字提供时)中。
如果函数定义中不存在 args 和 kwargs,则除了函数定义中显式指定的参数之外,调用者将不允许添加更多参数用于函数调用。

在函数定义中,您需要首先指定不带默认初始值设定项的显式参数,其次是带默认初始值设定项的显式参数,第三是参数列表,最后是关键字参数字典。

函数调用

调用函数的方法有很多种。例如,以下调用将产生相同的结果:

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

也就是说,函数参数通过它们的位置(位置或非关键字参数)或它们指定的名称(关键字参数)来解析。

调用函数时,您需要首先放置非关键字参数,最后放置关键字参数,例如

# 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}

现在,不适合函数定义中指定参数列表的位置参数将被附加到参数列表*args,以及不适合函数定义中指定参数列表的关键字参数将被插入到关键字参数字典**kwargs中。

Probably you are confusing the function definition and the function call syntax a bit.

patch1 is not a keyword arg, it's a positional arg with a default argument value assigned.

*patches is an argument list, and not a positional argument.


Please have a look at this section from the official tutorials:

Now let me summarize the main points using this function as an example:

def f1(a1, a2, a3=None, *args, **kwargs):
  print a1, a2, a3, args, kwargs

Function Definition

You have a number of arguments that are defined explicitly by name (a1, a2 and a3), of which a3 will be default initialized by None if not supplied during call. The arguments a1 and a2 need to be supplied in any valid call of that function.

The function may be called with additional arguments that will appear in the dictionary kwargs (when supplied by keyword) or in the list args (when not supplied by keyword).
If args and kwargs would not be present in the function definition, the caller would not be allowed to add more arguments besides those explicitly named in the function definition for the function call.

In the function definition you need to specify the explicit arguments without default initializer first, second the explicit arguments with default initializer, third the argument list, lastly the keyword argument dictionary.

Function Call

There are various ways to call the function. For example will the following calls produce equal results:

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

That is, the function arguments are resolved either by their position (positional, or non-keyword arguments) or by their specified name (keyword arguments).

When calling the function you need to put the non-keyword arguments first and lastly the keyword arguments, e.g.

# 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}

Now, positional arguments that don't fit into the list of specified arguments in the function definition will be appended to the argument list *args, and keyword arguments that don't fit into the list of specified arguments in the function definition will be inserted into the keyword argument dictionary **kwargs.

南冥有猫 2024-12-28 01:42:55

因为如果键的位置明确,则将键传递给关键字参数可以是可选的。观察:

>>> 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

如您所见,省略 patch1 的键会使该参数成为非关键字参数,从而不会触发 SyntaxError 异常。


编辑: moooeeeeep 在他的回答中说

“patch1 不是关键字参数,它是分配了默认参数值的位置参数。”

这并没有错,但在我看来,以下情况说明了为什么这样的定义不明确:

>>> 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

HTH!

Because passing the key to a keyword argument can be optional if the position of it is unambiguous. Observe:

>>> 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

As you can see, omitting the key of patch1 render that argument a non-keyword one, thus not triggering the SyntaxError exception.


EDIT: moooeeeep in his answer says that

"patch1 is not a keyword arg, it's a positional arg with a default argument value assigned."

This is not wrong, but the following-case IMO, illustrates why such definition is ambiguous:

>>> 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

HTH!

雅心素梦 2024-12-28 01:42:55

我相信当使用以下方式调用函数时,

function(arg1="value")

这将使用“关键字”参数,但是当使用以下方式定义函数的接口时:

def function(arg1="value"):

您正在定义“默认值”。 ()

所以回答你的问题;在位置参数之后有默认值是完全正常的,在关键字之前使用非关键字参数调用函数也是如此。

另请注意,调用函数时,关键字后不能有非关键字参数。

I believe when calling a function with:

function(arg1="value")

This would be using a "keyword" argument, but when defining a function's interface with:

def function(arg1="value"):

you're defining a "default value". ()

So to answer your question; Having a default value after a positional argument is perfectly normal, and so is calling a function with a non-keyword argument before a keyword.

Also note, when calling a function, you cannot have a non-keyword argument after a keyword.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文