0

如何解决这个问题?用另一个签名修补对象方法(例如,附加参数。我尝试绑定可选参数,但这似乎不起作用。我不能在这里使用普通的猴子修补,因为修补的类在一个我无法以其他方式修补它的位置。

任何帮助表示赞赏。

import mock
import functools

# this class lives in another (unchangeable) module, __len__ method has to be patched
class ToOverride(object):
    def __len__(self):
        raise NotImplementedError()

# this code is changeable
def my_len(self, arg):
    return arg+1

my_len_bound = functools.partial(my_len, arg=1)

with mock.patch.object(ToOverride, '__len__', my_len_bound):
    inst = ToOverride()
    print len(inst) # expected output: 2

调用上下文 mock.patch.object 时,我收到以下错误:

TypeError                                 Traceback (most recent call last)
<ipython-input-7-bfdb41d8628f> in <module>()
      1 with mock.patch.object(ToOverride, '__len__', my_len_bound):
      2     inst = ToOverride()
----> 3     print len(inst)

TypeError: my_len() takes exactly 2 arguments (1 given)

但是使用 None 作为第一个参数调用 my_len 可以按预期工作(打印输出 2)。

假设可以简单地使用猴子补丁,它可以工作,如果手动调用len并将实例作为第一个参数。但这当然是不希望的:

ToOverride.__len__ = my_len_bound
inst = ToOverride()
print( inst.__len__(inst)) # 2
4

1 回答 1

1

通过使用闭包模式,可以避免使用对类方法不起作用的 functools partial。

def bind_arg(arg):
    def my_len(self, arg):
        return arg+1
    return my_len
于 2015-11-10T13:30:06.563 回答