1
我想学习一些高级修饰器的用法。具体来说,我试图通过一个函数中的装饰器来修补类的方法。python monkey通过修饰器修补函数中的对象的方法
这是一个基本的例子来说明我想要做什么。我有一个功能something
,它可以做一些事情;并且在该函数内有一个类的实例。那个例子我想猴子补丁。
from functools import update_wrapper
class Foobar:
def get_something(self):
return "apple"
class FakeFoobar:
def get_something(self):
return "orange"
class my_decorator:
def __init__(self, original_function):
self._original_function = original_function
update_wrapper(self, original_function)
def __call__(self, *args, **kwargs):
# some magic here?
return self._original_function(*args, **kwargs)
@my_decorator
def something():
f = Foobar()
return f.get_something()
if __name__ == '__main__':
print(something())
我想无论是想做一个1比1置换Foobar
到FakeFoobar
或猴补丁Foobar
的get_something
方法FakeFoobar
的get_something
方法。
当我运行上面的代码,我得到如下:
>>> something()
'apple'
>>>
我想找到某种方式增加了Foobar
的get_something
方法,使我们得到如下输出:
>>> something()
'orange'
>>>
unittests
库中有一个mock
模块,但是,我不清楚如何将其用于我的用例。我很相信,不会将参数传递给装饰器,也不会像something
函数那样引入额外的参数,因为很多mock库显示的示例都是如此。
我还注意到moto library正在完成类似于我正在做的事情。我试着深入了解源代码,但对于我正在尝试做的事情来说似乎相当复杂。
这非常接近。问题在于它更新了整个模块的全局变量,所以如果我在'something'函数之外重新实例化'Foobar',我会返回'FakeFoobar',这是不可取的。 – user5038859
@ user5038859:您可以随时恢复变量,就像我刚更新的答案一样。 – SuperSaiyan
这就是我一直在寻找的,谢谢。在将此标记为答案之前,请接受我对python3支持的编辑。 – user5038859