如何记录功能执行的成功开始和结束?

时间:2020-09-26 13:31:52

标签: python-2.7

我正在调试代码。我在python 2中有很多行的代码。有些函数执行时间很长。为了检查功能是否成功完成,我正在做以下丑陋的事情:

print("creating an object... "), # a comma here to print a subsequent print in one line 
obj = TimeDemandingFunction()
print("end")

有没有最好的记录方法?

P.S。 函数TimeDemandingFunction()来自外部库

2 个答案:

答案 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__'
相关问题