Getting caller name in double-decorator in Python
为了跟踪代码中的竞争条件,我需要显示调用者名称和操作所需的时间。
以下代码输出:
1 2 | 2018-02-06 19:00:11.418800: get_data() called by **wrappe**r() (0:00:00.001010) test result: PASS |
如何输出调用者名称而不是装饰者函数名称,例如:
1 2 | 2018-02-06 19:05:47.617679: get_data() called by **test_get_data**() (0:00:00.034116) test result: PASS |
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | from datetime import datetime import time, inspect class Timer(): def __init__(self): self.time_start = datetime.now() def stop(self): return (datetime.now() - self.time_start) class Test2Decorators(): def caller(callee): def timer(callee): def wrapper(*args, **kwargs): get_data_timer = Timer() result = callee(*args, **kwargs) print ' (%s)' % get_data_timer.stop() return result return wrapper @timer def wrapper(*args, **kwargs): curframe = inspect.currentframe() calframe = inspect.getouterframes(curframe, 2) print '%s: %s() called by %s()' % (datetime.now(), callee.__name__, calframe[1][3]), return callee(*args, **kwargs) return wrapper @caller def get_data(self, product_id = None, product_name = None): return 'test result: PASS' def test_get_data(): print class_inst.get_data('beer', '32445256') time.sleep(1) class_inst = Test2Decorators() test_get_data() |
我只是这样想出来的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | from datetime import datetime import inspect import time class Timer(): def __init__(self): self.time_start = datetime.now() def stop(self): return (datetime.now() - self.time_start) class Test2Decorators(): def caller(callee): def timer(callee): def wrapper(*args, **kwargs): get_data_timer = Timer() result = callee(*args, **kwargs) print '%s()' % inspect.stack()[1][3], print ' (%s)' % get_data_timer.stop() return result return wrapper @timer def wrapper(*args, **kwargs): print '%s: %s() called by' % (datetime.now(), callee.__name__), return callee(*args, **kwargs) return wrapper @caller def get_data(self, product_id = None, product_name = None): return 'test result: PASS' def test_get_data(): while True: print class_inst.get_data('beer', '32445256') time.sleep(1) class_inst = Test2Decorators() test_get_data() |