我想在某个类中进行调用时记录调试信息。记录的数据是:
- 函数名
- 从哪里调用函数的堆栈跟踪
- 函数执行的时间
- args 和 kwargs 传递给函数
我希望包装器相当通用。同时,包装应该在运行时进行。我制作了以下包装类来记录信息并将调用委托给原始实例。
import datetime
import traceback
from functools import partial
from logging_module import db_log
class BaseWrapper(object):
def __init__(self, item):
self._item = item
def __getattr__(self, attr):
return getattr(self._item, attr)
class DBLogWrapper(BaseWrapper):
@staticmethod
def _time_method(method):
name = "{0}.{1}.{2}".format(
method.im_class.__module__,
method.im_class.__name__,
method.__name__
)
def timed_method(self, *args, **kwargs):
begin = datetime.datetime.now()
return_val = method.im_func(self, *args, **kwargs)
end = datetime.datetime.now()
trace = traceback.format_stack()
db_log(
name,
begin,
end,
info={
'args': args,
'kwargs': kwargs,
'trace': trace
}
)
return return_val
return timed_method
def __init__(self, item, methods):
super(DBLogWrapper, self).__init__(item)
for method in methods:
class_method = getattr(item, method)
wrapped_method = DBLogWrapper._time_method(class_method)
wrapped_method = partial(wrapped_method, self._item)
setattr(self, method, wrapped_method)
示例用法:
class MyClass(object):
def hello(self, greeting):
print greeting
def goodbye(self):
print 'Good Bye'
a = MyClass()
if DEBUG:
a = DBLogWrapper(a, ['hello'])
a.hello()
a.goodbye()
在这种情况下,调用hello
将被记录,但调用goodbye
不会。
然而,对于一个看起来应该很简单的任务来说,这似乎有点过头了。我正在寻找有关如何改进上述代码或完全不同的方法的建议。