我很难总结这个问题,所以我会描述我想要做的事情:
我正在为某种产品编写测试解决方案,比方说微波炉。目的是在使用微波炉的同时测量各种资源。为此,我写了一个名为measure()
的上下文管理器。
使用微波API我编写了一个模拟微波基本用例的函数,并用一个完成所有测量的函数进行装饰:
def test_function(fn):
def wrapper(*args, **kwargs):
with measure():
fn(*args, **kwargs)
return wrapper
@test_function
def prepare_food():
microwave = Microwave()
microwave.open_door()
microwave.insert_food()
microwave.close_door()
microwave.turn_on(seconds = 60)
prepare_food()
当然,微波炉只是一个例子,我有很多这样的微波炉"。
经过几天的测试和测量后,我的团队决定分别测量每个动作,这意味着我的测试功能现在看起来像这样:
def test_prepare_food():
microwave = Microwave()
actions = {
microwave.open_door : [],
microwave.insert_food : [],
microwave.close_door() : [],
microwave.turn_on : [60]
}
for (action, args) in actions.items():
with measure():
action(*args)
新test_prepare_food
的问题是,现在每个prepare_food
函数,我需要添加另一个test_*
函数(我有很多)。
我正在寻找一种优雅的方式来保持我的prepare_food
功能相同,并用另一个功能包装它,这样我仍然可以获得与test_prepare_food
中相同的功能。
修改
目标是建立一个不依赖于prepare_food()
实施的解决方案,以便prepare_food()
中的更改不需要进行其他更改。此外,解决方案不应影响prepare_food
未使用的方法。
换句话说,我希望能够进入" prepare_food
并且能够在每行之前和之后执行代码。这类似于调试时所做的事情,但我找不到任何相似的东西。
有什么想法吗?
谢谢!
答案 0 :(得分:2)
您可以使用measure
方法修饰Microwave类的每个实例方法。这可以通过Microwave类上的类装饰器来完成。对于这个例子,我只是通过一种方法修改Microwave类。完成工作的方法是wrap
和wrap_method
。
import inspect
class measure(object):
def __enter__(self):
print "Enter measure."
def __exit__(self, *args):
print "Exit measure."
class Microwave(object):
def f(self, x):
print "f: %s" % x
def g(self, x):
print "g: %s" % x
def wrap_method(method):
def wrapper(*args, **kwargs):
with measure():
method(*args, **kwargs)
return wrapper
def wrap(cls):
for name, method in inspect.getmembers(cls, predicate=inspect.ismethod):
setattr(cls, name, wrap_method(method))
wrap(Microwave)
m = Microwave()
m.f(1)
m.g(2)
输出是:
Enter measure.
f: 1
Exit measure.
Enter measure.
g: 2
Exit measure.