我有很多课程。其中一些初始化很慢,我想通过使用cached properties来延迟一些初始化。第一步是确定哪些是罪魁祸首。所以我想计算以下代码:
class MyClass:
def __init__(self, ....):
# start measurement
...
# end measurement, report
我的要求是:
所以我的第一个想法是实现一个通用的timeme
函数:
def timeme(func):
def f(*args, **kwargs):
start = # get start timestamp
result = func(*args, **kwargs)
end = # get end timestamp
# report timespan
return result
return f
(可用于计算任何类型的函数,而不仅仅是类方法)
现在我可以做到:
class MyClass:
@timeme
def __init__(self, ....):
...
还有更多的 pythonic 方式吗?一些标准库支持这个?工具支持?这种方法有任何明显的缺点吗?
答案 0 :(得分:0)
标准库中没有这样的内容,除了cProfile
进行常规分析。
我建议您创建一个简单的元类,如果设置了某个全局/环境变量,它将包装__init__
方法。这样,您就不需要使用调试/分析装饰器来混淆代码。
只是一个起点(尚未测试过):
import functools
# Python 3.3 for time.monotonic is required
import time
class TimedMeta(type):
timing_enabled = True
@classmethod
def _wrap_timeit(mcls, cls_name, meth):
@functools.wraps(meth)
def wrapped(*args, **kwargs):
start = time.monotonic()
try:
return meth(*args, **kwargs)
finally:
end = time.monotonic()
mcls._record_timing(cls_name, end - start)
@classmethod
def _record_timing(mcls, cls_name, timing):
raise NotImplementedError
def __new__(mcls, name, bases, dct):
if mcls.timing_enabled:
try:
init = dct['__init__']
except KeyError:
pass
else:
dct['__init__'] = mcls._wrap_timeit(name, init)
return super().__new__(mcls, name, bases, dct)
class Timed(metaclass=TimingMeta):
pass
class Foo(Timed):
def __init__(self):
time.sleep(1.0)