理解 python3 函数中的 '*' "keyword only" 参数符号
understanding '*' "keyword only" argument notation in python3 functions
我在仅关键字参数上遇到了 keyword only arguments feature in python3 when used with partial. Other info 的一些困难行为。
这是我的代码:
def awesome_function(a = 0, b = 0, *, prefix):
print('a ->', a)
print('b ->', b)
print('prefix ->', prefix)
return prefix + str(a+b)
以下是我对partial的理解:
>>> two_pow = partial(pow, 2)
>>> two_pow(5)
32
>>>
我的理解是在上面的例子中,partial
使 pow
的第二个参数成为 two_pow
的唯一参数。
我的问题是为什么以下操作有效:
>>> g = partial(awesome_function, prefix='$')
>>> g(3, 5)
a -> 3
b -> 5
prefix -> $
''
>>>
但是我在这方面遇到了错误:
>>> awesome_function(prefix='$', 3, 5)
File "<stdin>", line 1
SyntaxError: non-keyword arg after keyword arg
>>>
我知道我可以通过
直接调用awesome_function
>>> awesome_function(prefix='$', a = 3, b = 5)
a -> 3
b -> 5
prefix -> $
''
>>>
你得到的错误 - SyntaxError: non-keyword arg after keyword arg
- 是因为你试图在关键字参数之后发送位置参数(如 3,5
),这不是有效的语法,因此是语法错误。在函数调用中 -
awesome_function(prefix='$', 3, 5)
^ ^ ^
| These two are the positional argument.
----- This is the keyword argument.
它在使用 functools.partial
时有效,因为 functools.partial
知道将位置参数放在关键字参数之前,因此当您使用位置参数调用部分函数 - g()
- 时,它会发送那些关键字参数之前的位置参数。因此,在你的情况下 g(3, 5) ==> awesome_function(3, 5, prefix='$')
.
一个简单的例子来说明这一点 -
>>> from functools import partial
>>> def func(a=0,b=1):
... print(a,b)
...
>>> ptfunc = partial(func,a=10)
>>> ptfunc(20)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: func() got multiple values for argument 'a'
在上面的例子中,当我们调用ptfunc(20)
时,20
首先作为位置参数被传递,然后关键字参数a=10
被传递,因此它抱怨它得到了参数 a
.
的多个值
中给出
functools.partial
is Roughly equivalent to:
def partial(func, *args, **keywords):
def newfunc(*fargs, **fkeywords):
newkeywords = keywords.copy()
newkeywords.update(fkeywords)
return func(*(args + fargs), **newkeywords)
newfunc.func = func
newfunc.args = args
newfunc.keywords = keywords
return newfunc
根据function calls in Python的语义,传递参数的规则如下
argument_list ::= positional_arguments ["," keyword_arguments]
["," "*" expression] ["," keyword_arguments]
["," "**" expression]
| keyword_arguments ["," "*" expression]
["," keyword_arguments] ["," "**" expression]
| "*" expression ["," keyword_arguments] ["," "**" expression]
| "**" expression
正如您在此处看到的,位置参数应始终出现在函数调用的开头。他们不能出现在其他任何地方。当你这样做时
awesome_function(prefix='$', 3, 5)
它违反了上述规则,因为您在关键字参数 (prefix
) 之后传递了两个位置参数(3
和 5
)。这就是为什么您得到 SyntaxError
,因为 Python 无法解析函数调用表达式。
但是,当您使用 partial
时它会起作用,因为 partial
创建一个新的函数对象并存储要传递给它的所有参数。当您实际调用 partial
返回的函数对象时,它首先应用所有位置参数,然后应用关键字参数。
我在仅关键字参数上遇到了 keyword only arguments feature in python3 when used with partial. Other info 的一些困难行为。
这是我的代码:
def awesome_function(a = 0, b = 0, *, prefix):
print('a ->', a)
print('b ->', b)
print('prefix ->', prefix)
return prefix + str(a+b)
以下是我对partial的理解:
>>> two_pow = partial(pow, 2)
>>> two_pow(5)
32
>>>
我的理解是在上面的例子中,partial
使 pow
的第二个参数成为 two_pow
的唯一参数。
我的问题是为什么以下操作有效:
>>> g = partial(awesome_function, prefix='$')
>>> g(3, 5)
a -> 3
b -> 5
prefix -> $
''
>>>
但是我在这方面遇到了错误:
>>> awesome_function(prefix='$', 3, 5)
File "<stdin>", line 1
SyntaxError: non-keyword arg after keyword arg
>>>
我知道我可以通过
直接调用awesome_function
>>> awesome_function(prefix='$', a = 3, b = 5)
a -> 3
b -> 5
prefix -> $
''
>>>
你得到的错误 - SyntaxError: non-keyword arg after keyword arg
- 是因为你试图在关键字参数之后发送位置参数(如 3,5
),这不是有效的语法,因此是语法错误。在函数调用中 -
awesome_function(prefix='$', 3, 5)
^ ^ ^
| These two are the positional argument.
----- This is the keyword argument.
它在使用 functools.partial
时有效,因为 functools.partial
知道将位置参数放在关键字参数之前,因此当您使用位置参数调用部分函数 - g()
- 时,它会发送那些关键字参数之前的位置参数。因此,在你的情况下 g(3, 5) ==> awesome_function(3, 5, prefix='$')
.
一个简单的例子来说明这一点 -
>>> from functools import partial
>>> def func(a=0,b=1):
... print(a,b)
...
>>> ptfunc = partial(func,a=10)
>>> ptfunc(20)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: func() got multiple values for argument 'a'
在上面的例子中,当我们调用ptfunc(20)
时,20
首先作为位置参数被传递,然后关键字参数a=10
被传递,因此它抱怨它得到了参数 a
.
中给出
functools.partial
is Roughly equivalent to:def partial(func, *args, **keywords): def newfunc(*fargs, **fkeywords): newkeywords = keywords.copy() newkeywords.update(fkeywords) return func(*(args + fargs), **newkeywords) newfunc.func = func newfunc.args = args newfunc.keywords = keywords return newfunc
根据function calls in Python的语义,传递参数的规则如下
argument_list ::= positional_arguments ["," keyword_arguments]
["," "*" expression] ["," keyword_arguments]
["," "**" expression]
| keyword_arguments ["," "*" expression]
["," keyword_arguments] ["," "**" expression]
| "*" expression ["," keyword_arguments] ["," "**" expression]
| "**" expression
正如您在此处看到的,位置参数应始终出现在函数调用的开头。他们不能出现在其他任何地方。当你这样做时
awesome_function(prefix='$', 3, 5)
它违反了上述规则,因为您在关键字参数 (prefix
) 之后传递了两个位置参数(3
和 5
)。这就是为什么您得到 SyntaxError
,因为 Python 无法解析函数调用表达式。
但是,当您使用 partial
时它会起作用,因为 partial
创建一个新的函数对象并存储要传递给它的所有参数。当您实际调用 partial
返回的函数对象时,它首先应用所有位置参数,然后应用关键字参数。