4

しばらく失敗した後、この奇跡的な Web サイトに助けを求めています。今私の問題のために:関数の実行経過時間(関数の実行)を次のようなログファイルに書き込むデコレータを作成したいと思います。

@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

何か案は?

4

3 に答える 3

6

これを達成するために何をしなければならないかについての基本的な概要を説明します。以下は、2 つのパラメーターを受け取り、関数を実行するデコレーターです。不足している機能はコメントとして表示され、次のように追加します。

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します。

@log_time('foo.txt', 40)
def foo(i, j):
    print(i, j)

foo(1, 2)

foo を取得して実行します。time適切にそれを行い、内容をファイルに書き込む必要があります。デコレータをさらに試して、よく読んでください。デコレータに関するすばらしい記事が Python Wiki にあります。

于 2016-01-24T21:29:46.133 に答える
3

すぐに組み立てられましたが、いくつかの関数で @timeit を使用したテストで動作しました。

import logging
logging.basicConfig(
    level=logging.DEBUG, 
    filename='myProgramLog.txt', 
    format=' %(asctime)s - %(levelname)s - %(message)s')

import time                                                

def timeit(method):

    def timed(*args, **kw):
        ts = time.time()
        result = method(*args, **kw)
        te = time.time()

        logging.debug('%r (%r, %r) %2.2f sec' % \
              (method.__name__, args, kw, te-ts))
        return result

    return timed

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

編集: Python にはかなり優れたログ モジュールが付属していることがわかります。なぜ車輪を再発明するのですか?

于 2016-01-24T21:29:34.783 に答える
3

さて、最後にスレッドで何かを理解しました。すべての提案をありがとう!

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

欠点の 1 つは、関数の戻り値を簡単に取得できないことです (少なくとも、私はまだ理解していません)。

EDIT1: 不要な変数を削除し、ログ書き込み用の適切な形式を追加しました (これを参照)

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
于 2016-01-24T23:23:19.813 に答える