functools.partial希望将位置参数用作关键字参数
我在尝试理解 partial
的用法:
import functools
def f(x,y) :
print x+y
g0 = functools.partial( f, 3 )
g0(1)
4 # Works as expected
输入:
g1 = functools.partial( f, y=3 )
g1(1)
4 # Works as expected
输入:
g2 = functools.partial( f, x=3 )
g2(1)
TypeError: f() got multiple values for keyword argument 'x'
如果我把 y
当作关键字参数来用,TypeError
就不会出现了:
输入:
g2( y=1 )
4
那这个 TypeError
是怎么产生的呢?
3 个回答
0
这不是答案,而是一个后续问题(因为我没有50的声望,不能评论),你能不能详细解释一下,或者用简单的词语说一下,因为这里的回答我看不太懂。
我在使用Maya里的一个按钮时遇到了类似的问题。
import maya.cmds as cmds
from functools import partial
class Myclass(object):
def __init__(self):
pass
def createui(self):
derp = cmds.window()
cmds.formLayout()
cmds.button(label = "w/e", c = partial(self.f, x = 3))
cmds.showWindow(derp)
def f(self, x = 5, y = 3, *_):
print(x+y)
herp = Myclass()
herp.createui()
点击这个按钮会出现同样的错误:“得到了多个值用于关键字参数'x'”。
尽管我以为传递的参数是对类的调用,但实际上却是对UI元素本身的一个愚蠢调用(通常是一个False的值),这个值应该放在*_这个通用参数里,然后再是关键字参数x。
1
为了更详细地解释@Martijn-Pieters的回答,这里介绍了如何保持第二个参数的位置特性。在这里,传给g2的参数是作为y来传递的:
def f(x,y) :
print x+y
g2 = functools.partial( f, *[3] )
g2(1)
当我们想要替换f的初始参数时,这种方法是有效的。不过,我不知道如何使用partial
来只替换一个三参数函数的第二个参数,同时让第一个和第三个参数按位置传递。 但你可以通过使用一个lambda表达式来实现这个功能。
53
这其实和 functools.partial
没什么关系。你实际上是这样调用你的函数的:
f(1, x=3)
在Python中,首先会处理位置参数,而你的第一个参数是 x
。接着,关键字参数会被应用,而你又一次提供了 x
。
functools.partial()
并没有办法检测到你已经把第一个位置参数当作关键字参数提供了。它不会通过用 y=
关键字参数来替换位置参数来增强你的调用。
在混合使用位置参数和关键字参数时,你必须小心不要重复使用同一个参数。