使用装饰器记录执行时间

时间:2016-01-24 21:18:55

标签: python python-2.7 logging python-decorators functools

在我尝试了一段时间失败之后,我正在寻求这个神奇网站的帮助。现在我的问题是:我想创建一个装饰器,将函数的经过执行时间( 执行函数)写入日志文件,如:

@log_time("log.txt", 35)
def some_function(...):
    ...
    return result

from functools import wraps

def log_time(path_to_logfile, interval):
    ...

以便log.txt看起来像

Time elapsed: 0h 0m 35s
Time elapsed: 0h 1m 10s
Time elapsed: 0h 1m 45s

有什么想法吗?

3 个答案:

答案 0 :(得分:4)

我将为您提供有关完成此操作必须执行的操作的基本概述。以下是装饰器,它接受两个参数,并执行该函数。缺少的功能表示为注释,将它们添加到:

-force-cat
       skips media configuration check when concatenating file.

您现在可以装饰函数,输出将以def log_time(path_to_logfile, interval): def log(func): # 'wrap' this puppy up if needed def wrapped(*args, **kwargs): # start timing func(*args, **kwargs) # stop timing with open(path_to_logfile, 'a') as f: pass # functionality return wrapped return log 编写。因此,例如,在此处装饰path_to_logfile

foo

将采取foo并执行它。您需要@log_time('foo.txt', 40) def foo(i, j): print(i, j) foo(1, 2) 它,并将内容写入您的文件。您应该更多地尝试装饰器并阅读它们,这是一篇关于Decorators exist at the Python Wiki的好文章。

答案 1 :(得分:2)

好吧,我最终想到了线程。感谢您的所有建议!

import codecs, threading, time
from functools import wraps

def log_time(logpath="log.txt", interval=5):

    def log_time_decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            t = threading.Thread(target=func, args=args, kwargs=kwargs)
            log_entries = 0
            with codecs.open(logpath, "wb", "utf-8") as logfile:
               start_time = time.time()
               t.start()
               while t.is_alive():
                   elapsed_time = (time.time() - start_time)
                   if elapsed_time > interval * log_entries:
                       m, s = divmod(elapsed_time, 60)
                       h, m = divmod(m, 60)
                       logfile.write("Elapsed time: %2dh %2dm %2ds\n" %(h, m, s))
                       log_entries += 1
        return wrapper
    return log_time_decorator

一个缺点可能是你不能轻易检索到函数的返回值(至少我还没想到它)。

EDIT1:删除了一个不必要的变量并为记录添加了一个很好的格式(参见this

EDIT2:即使其他用户拒绝了他的编辑,我也想要添加Piotr Dabkowski版本,因为它适用于返回值:

def log_time(logpath="log.txt", interval=5):

    def log_time_decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            RESULT = [None]
            def temp():
                RESULT[0] = func(*args, **kwargs)
            t = threading.Thread(target=temp)
            log_entries = 0
            with codecs.open(logpath, "wb", "utf-8") as logfile:
               start_time = time.time()
               t.start()
               while t.is_alive():
                   elapsed_time = (time.time() - start_time)
                   if elapsed_time > interval * log_entries:
                       m, s = divmod(elapsed_time, 60)
                       h, m = divmod(m, 60)
                       logfile.write("Elapsed time: %2dh %2dm %2ds\n" %(h, m, s))
                       log_entries += 1
            return RESULT[0]
        return wrapper
    return log_time_decorator

答案 2 :(得分:1)

快速整理,但在@timeit的测试中使用了一些函数。

puts "Please enter the text"
text = gets.chomp
text.downcase!
words = text.split(" ")
#ask for user input and turn the input into an array

puts "Please enter the redact word"
redact = gets.chomp
redact.downcase!
redacts = redact.split(" ")
#ask the user what words they want to redact in their input

redacts.each do |redact|
    words.delete(redact)
end
#print out the redacted input (including irredacted and redacted words)
print(words.join(" "))

来源:https://www.andreas-jung.com/contents/a-python-decorator-for-measuring-the-execution-time-of-methodshttps://automatetheboringstuff.com/chapter10/

编辑:我发现Python附带了一个非常好的日志记录模块;为什么重新发明轮子?