Python运算符.methodcaller()未正确处理参数



我想在映射函数中使用python中的operator.methodcaller()函数。然而,在传递参数列表时,我收到了一些奇怪的错误消息。

python文档让我相信,这通常不会成为问题:

返回一个可调用对象,该对象调用其操作数上的方法名称。如果提供了额外的参数和/或关键字参数,它们也将提供给方法。例如:

在f=methodcaller('name'(之后,调用f(b(返回b.name((。

在f=methodcaller('name','foo',bar=1(之后,调用f(b(返回b.name('fo',bar=1(。

我哪里出错了?有什么简单的替代方案吗?

我编了一个简短的代码示例来说明我的问题:

import operator
class CallTest:
def __init__(self):
self.x = 1
self.y = 2
def mutate(self, new_x, some_y = 2):
self.x = new_x
self.y = some_y
def map_something(func, iterable):
""" This doesn't work and that's as expected. The error shows that the methodcaller is referencing
the correct object though.
"""
for i in iterable:
func(i)
def map_something_else(func, iterable, *args, **kwargs):
""" Why doesn't this work? And are there alternatives? """
for i in iterable:
func(i, *args, **kwargs)
def map_differently(func, iterable, *args, **kwargs):
""" This works as expected but is kind of pointless in this case because i could replace this
with getattr()
"""
for i in iterable:
operator.methodcaller(func, *args, ** kwargs)(i)

if __name__ == '__main__':
caller = operator.methodcaller('mutate')
objs = [CallTest() for i in range(0, 2)]
# map_something(caller, objs) # As expected we get: TypeError: mutate() missing 1 required positional argument: 'new_x'
# map_something_else(caller, objs, 5) # TypeError: methodcaller expected 1 argument, got 2
# map_something_else(caller, objs, 5, some_y=3) # TypeError: methodcaller() takes no keyword arguments
map_differently('mutate', objs, 5, some_y=3) # This works as expected.
for obj in objs:
print(obj.x, obj.y)

operator.methodcaller在创建时只接受额外的参数。当调用methodcaller时,您正试图提供额外的参数。

它是这样工作的:

mc = operator.methodcaller('method_name', additional_arg)
mc(obj)

不是这样的:

mc = operator.methodcaller('method_name')
mc(obj, additional_arg)

这就是你的map_something_else想要做的

最新更新