【发布时间】:2018-04-12 22:18:13
【问题描述】:
我有一些类有一个字段spent_times。 spent_times 是一个列表,这个类的所有方法都会写入一些信息,这对于日志记录很有价值。
另外,我有一个装饰器,它计算每个函数的执行时间并将其写入spent_times。
这是我的装饰器的实现:
def timing(message):
def wrap(function):
def called(*args, **kwargs):
time_start = timer()
spent_time = round(timer() - time_start, 5)
if not args:
return function(*args, **kwargs), spent_time
obj = args[0]
if hasattr(obj, "spent_times"):
obj.spent_times.append("{}={:.5f}".format(message, spent_time))
return function(*args, **kwargs)
else:
logging.warning('Decorator allows to set spent_time attribute!')
return called
return wrap
正如你在我的装饰器中看到的,有一个检查,如果调用函数具有属性 self。
如果有,我可以当场在列表spent_times 中写入所需的信息,如果没有,装饰器会返回执行和函数本身所花费的时间。
我在一个模块中使用这个装饰器,第二种情况(当没有找到 self 时)属于这个模块中的一些其他函数,这些函数不属于定义了花费时间列表的类,但我在我的班级内部执行它们,所以我能够实现例如以下结构:
这是“外部”函数的声明
def calc_users(requests, priority):
# .....
在我的课堂中,我执行它并以这种方式更新我的花费时间列表:
response, spent_time = calc_users(requests, priority)
self.class_obj.spent_times.append("user_calculation={:.5f}".format(spent_time))
这不是很好,但至少可以正常工作。
现在,我在不同新模块中移动了我的类的一些功能,我想使用相同的装饰器时间。
有人可以帮我在新模块中实现这种计时实现吗?我不知道,我现在可以做什么来更新我的spent_times 列表。
这两个模块将同时工作,我无法创建类的对象并将其作为参数传递给新模块,因为(据我了解)将有两个对象并且花费时间不会正确更新.
也许有办法以某种方式传递对spent_times 的引用,但我不想在新模块中更改我的函数的参数,因为我认为在这种情况下,共享责任原则将被打破(装饰者负责用于记录,函数用于其操作)。
那么如何改进装饰器或如何将spent_times 列表传递给新模块?
任何帮助将不胜感激!
附:
也许将spent_times 设为全局变量? (在最坏的情况下)
【问题讨论】:
标签: python python-2.7 decorator