我正在调试代码。我在python 2中有很多行的代码。有些函数执行时间很长。为了检查功能是否成功完成,我正在做以下丑陋的事情:
print("creating an object... "), # a comma here to print a subsequent print in one line
obj = TimeDemandingFunction()
print("end")
有没有最好的记录方法?
P.S。
函数TimeDemandingFunction()
来自外部库。
答案 0 :(得分:1)
好吧,如果您只需要一个装饰器(例如,记录日志函数的执行时间),就可以使用以下代码:
import functools
import time
def my_custom_timer(func):
@functools.wraps(func)
def wrapper_timer(*args, **kwargs):
start_time = time.perf_counter()
value = func(*args, **kwargs)
end_time = time.perf_counter()
run_time = end_time - start_time
print(f"Finished {func.__name__!r} in {run_time:.4f} seconds.")
return value
return wrapper_timer
@my_custom_timer
def waste_some_time(num_times):
for _ in range(num_times):
sum([i**2 for i in range(10000)])
waste_some_time(2)
输出:
Finished 'waste_some_time' in 0.0050 seconds.
编辑: 这是您如何从另一个模块装饰功能的方法。首先,必须将其导入,然后将其放入功能块中。
@my_custom_timer
def find_evens(n):
return itertools.filterfalse(lambda x: x % 2, range(n))
evens = find_evens(20)
print(list(evens))
输出:
Finished 'find_evens' in 0.0000 seconds.
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
请注意,根据定义,装饰器是一个函数,该函数接受另一个函数并扩展后一个函数的行为,而无需显式修改它。
如果要在另一个模块中使用装饰器,则只需将其导入即可,就像导入其他功能一样。
from othermodule import your_decorator
@your_decorator
def some_function():
pass
答案 1 :(得分:0)
Baduker的答案促使我给出他的答案的修改版本。我将总结并举几个例子。 装饰器的构造类似于Baduker,但进行了一些修改:(1)通知功能已在调用函数的地方启动了该函数的调用信息(行数和使用的键),(2)编写了信息大约在最后的时间。下面,我举例说明如何将其用于外部功能:
import functools
import timeit
import sys
def my_custom_timer(func):
@functools.wraps(func)
def wrapper_timer(*args, **kwargs):
start_time = timeit.default_timer()
s = ''
for arg_name in kwargs:
s += arg_name + '; line=' + str(sys._getframe().f_back.f_lineno)
print("Started {!r}({!r}) ".format(func.__name__, s)),
value = func(*args, **kwargs)
end_time = timeit.default_timer()
run_time = end_time - start_time
print("Finished in {:.4f} seconds.".format(run_time))
return value
return wrapper_timer
然后是一个有趣的部分。首先,您需要找出函数的完整路径。使用想法here。简要地说,函数具有 module 属性:
>>> from math import sqrt
>>> sqrt.__module__
'math'
首先,让我们从某个模块中重新定义sqrt
函数:
import math
@my_custom_timer
def sqrt(*args, **kwargs):
return math.sqrt(*args, **kwargs)
如果内置模块有功能怎么办?没问题。答案是__builtin__
模块:
>>> print(divmod.__module__)
'__builtin__'