如何在Python中模拟函数以更改默认关键字参数

如何在Python中模拟函数以更改默认关键字参数,python,mocking,keyword-argument,Python,Mocking,Keyword Argument,我使用模拟库和unittest2来测试我的软件项目的不同方面 目前我有以下问题:是否可以模拟一个函数,使默认关键字参数不同,但功能仍然存在 假设我有以下代码 class C(): def fun(self, bool_arg = True): if bool_arg: return True else return False 如果我想模仿C.fun怎么办 C.fun = mock.Mock(???) 因此,C的每个实例都会将关键字“bool_ar

我使用模拟库和unittest2来测试我的软件项目的不同方面

目前我有以下问题:是否可以模拟一个函数,使默认关键字参数不同,但功能仍然存在

假设我有以下代码

class C():
  def fun(self, bool_arg = True):
    if bool_arg:
      return True
    else
      return False
如果我想模仿C.fun怎么办

C.fun = mock.Mock(???)
因此,C的每个实例都会将关键字“bool_arg”替换为False,而不是True,结果如下:

c = C()
c.fun()
返回:

假的


您可以尝试使用以下代码:

>>> import mock
>>> 
>>> class C():
...   def fun(self, bool_arg = True):
...     if bool_arg:
...       print "True"
...     else:
...       print "False"
... 
>>> c = C()
>>> funCopy = c.fun
>>> c.fun = mock.Mock(side_effect=lambda bool_arg=False: funCopy(bool_arg=bool_arg))
>>> c.fun()
False

希望这对您有所帮助,您也可以尝试包装您的函数。有什么事

def wrapper(func, bool_arg):
    def inner(*args, **kwargs):
        kwargs['bool_arg']=bool_arg
        return func(*args, **kwargs)
    return inner

应该有用

编辑

如果要更改类而不是特定实例的默认值,可以创建派生类并重新定义
fun
包装
C
的方法。线路上有些东西(我现在没有时间测试):

然后关于@Ber的建议,您可以定义
def wrapper(func,**wrapkwargs)
,然后代替
kwargs['bool\u arg']=bool\u arg
do

for i in wrapkwargs.iteritems():  #wrapkwargs is a dictionary
    kwargs[i[0]] = i[1]

我不知道你可以在
lambda
@jdotjdot中进行默认变量赋值,你是对的,但我认为如果mpaf提出这个问题,是因为他可以调用函数来更改默认变量值。@jdotjdot(英文)please@jdotjdot好啊没问题,对不起我的英语;)感谢这个解决方案,我会接受它,因为它是第一个,但我无法使它适用于我正在寻找的情况(可能我的问题不是太明确),即C类的每个实例都会替换关键字参数。很好。Thid可以扩展为包装任何函数,提供任何关键字参数列表。感谢您的回答!实际上,我正在寻找替换类default关键字参数的方法,以替换它的每个实例。但是我稍微修改了您的解决方案,因此我没有使用:c.fun=wrapper(…),而是使用了:class c.fun=wrapper(…)。它适用于所有情况!Ber,您如何概括上述内容以接受任何想要包装的关键字参数?@mpaf您的意思是您已经更改了C类的实现,用包装的版本替换了self.fun?@mpaf:如果您想更好地理解包装器(因此也就是装饰器),我建议您阅读并
class D(C):
    def fun(self, *args, **kwargs):
        f = wrapper(C.f, False)
        return f(*args, **kwargs)
for i in wrapkwargs.iteritems():  #wrapkwargs is a dictionary
    kwargs[i[0]] = i[1]