35

所以我想了解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'

如果我用作关键字参数,TypeError则消失:y

在:

g2( y=1 )

4

是什么原因导致的TypeError

4

3 回答 3

42

真的跟这个没关系functools.partial。你本质上是这样调用你的函数的:

f(1, x=3)

Python 首先满足位置参数,而您的第一个参数是x. 然后应用关键字参数,您再次提供x.

functools.partial()无法检测到您已经提供了第一个位置参数作为关键字参数。它不会通过用y=关键字参数替换位置参数来增加您的调用。

混合位置参数和关键字参数时,必须注意不要两次使用相同的参数。

于 2014-07-15T10:11:39.593 回答
1

为了扩展@Martijn-Pieters 的答案,这是您可以保留第二个参数的位置性质的方式。在这里,g2 的参数按位置传递为 y:

def f(x,y) :
    print x+y

g2 = functools.partial( f, *[3] )
g2(1)

当我们试图替换 f 的一组初始参数时,这很有效。我不知道如何使用partial来替换例如 3 参数函数的第二个参数,并允许第一个和第三个按位置传递。但是您可以使用 lambda 表达式来做到这一点。

于 2018-08-24T17:57:13.193 回答
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 值)应该放在 *_ catch all 参数中,然后是 x 的关键字参数.

于 2019-12-10T03:03:01.810 回答