我有一个函数,我正在尝试做一个部分版本,然后将这个部分函数应用到一个约简语句中。
部分函数本身起作用,因为我可以正常地用一组参数调用它,它将返回正确的答案。但是,如果在减缩下应用,它会中断。
例如;
import functools
test=[1,2,3,4]
def base_function(mult=10,a=0,b=0):
return(mult*(a+b))
#control function, should act like partial base_function with mult=1
def test_function1(a=0,b=0):
return(a+b)
#stupid partial function that has destroyed my friday afternoon
test_function2=functools.partial(base_function,mult=1)
print(test_function2.args) #returns ()
print(test_function2.keywords) #returns {'mult':1}
print(test_function1(a=1,b=2)) #returns 3 as expected
print(test_function2(a=1,b=2)) #returns 3 as expected! horray!
#so the partial function itself works when called normally
print(functools.reduce(test_function1,test,-20)) #returns -10
print(functools.reduce(test_function2,test,-20)) #returns TypeError: base_function() got multiple values for argument 'mult'作为一个额外的奖励,如果我改变代码,使多个正位参数和更新的部分函数如此;
def base_function(mult,a=0,b=0):
return(mult*(a+b))
def test_function1(a=0,b=0):
return(a+b)
test_function2=functools.partial(base_function,1)
print(test_function2.args)
print(test_function2.keywords)血淋淋的东西和reduce语句完全一样。
有人能给我解释一下吗?对于这种类型的错误,我能找到的唯一答案似乎适用于在函数中调用某个东西作为关键字和普通参数的情况--据我所知,在这里还没有发生这种情况--如果是这样的话,部分函数在正常调用时不应该工作得很好。“解决办法”使一个位置论点是可行的,但我很想知道是什么导致了这一错误,因为显然,我一定是误解了一些关键的东西。
编辑:感谢那些回答了我的问题的海报--我现在明白了为什么会发生这种情况,为什么要重新排列论点,或者让它们的位置来解决问题,所以我把它标记为“解决了”。
然而,我想知道是否有一种“整洁”的方法--一个类似于部分的操作符,它不仅返回一个部分对象,如果参数被正确传递,该对象的作用就像期望的函数,但是实际上返回一个任意的期望函数,而不需要预先定义这个任意函数。例:
import functools
def base_function(mult=10,a=0,b=0):
return(mult*(a+b))
def test_function1(a=0,b=0):
return(a+b)
test_function2=partial_like_operator(base_function,mult=1)
print(test_function2==test_function1) #prints true发布于 2015-10-23 20:34:39
@horoy是对的。
另一种解释方法是:
在引擎盖下,对reduce的调用会产生错误,结果是调用如下所示:
test_function2(x, y, mult=1)其中x和y是reduce函数的局部变量。
你可以试一试,很容易地看到这不是一个有效的调用。传递的第一个参数必须对应于mult,因为这是函数的第一个参数,但是mult被传递给另一个值,作为kw。
在调用起作用的部分函数的测试中,您将a和b作为kwargs传递,从而绕过了这个问题。
结论是,在使用部分时,最好是将函数的最后参数绑定在一起,而不是第一个参数。
发布于 2015-10-23 18:30:28
这一切都是按参数排序的。在您的测试用例中,通过使用a=1, b=2和使用第一个参数的reduce()显式地绕过顺序,它确实失败了。
然而,如果你扭转了它,这似乎是可行的:
def base_function(a=0, b=0, mult=10):
return mult * (a + b)至少这对我有好处!
在您的情况下,以下内容也很可能失败:
print(test_function2(1, 2))这是因为它试图设置两次mult .
https://stackoverflow.com/questions/33307963
复制相似问题