【问题标题】:Getting caller name in double-decorator in Python在 Python 的双装饰器中获取调用者名称
【发布时间】:2018-02-06 18:14:33
【问题描述】:

为了在代码中跟踪竞争条件,我需要显示调用者姓名以及操作需要多长时间。

下面的代码输出:

2018-02-06 19:00:11.418800: get_data() called by **wrappe**r()  (0:00:00.001010)
test result: PASS

如何让它输出调用者名称而不是装饰器函数名称,例如:

2018-02-06 19:05:47.617679: get_data() called by **test_get_data**()  (0:00:00.034116)
test result: PASS

代码:

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()

【问题讨论】:

标签: python decorator


【解决方案1】:

我只是这样想的:

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()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-28
    • 2020-12-18
    • 1970-01-01
    • 2019-12-21
    • 2011-01-19
    相关资源
    最近更新 更多