一个装饰器,用于分析方法调用并记录分析结果

Weh*_*olt 20 python profiling decorator

我想创建一个装饰器,用于描述方法并记录结果.如何才能做到这一点?

det*_*tly 64

如果你想要正确的分析而不是计时,你可以使用cProfile(来自这个问题)的未记录的特征:

import cProfile

def profileit(func):
    def wrapper(*args, **kwargs):
        datafn = func.__name__ + ".profile" # Name the data file sensibly
        prof = cProfile.Profile()
        retval = prof.runcall(func, *args, **kwargs)
        prof.dump_stats(datafn)
        return retval

    return wrapper

@profileit
def function_you_want_to_profile(...)
    ...
Run Code Online (Sandbox Code Playgroud)

如果您想要更多地控制文件名,那么您将需要另一层间接:

import cProfile

def profileit(name):
    def inner(func):
        def wrapper(*args, **kwargs):
            prof = cProfile.Profile()
            retval = prof.runcall(func, *args, **kwargs)
            # Note use of name from outer scope
            prof.dump_stats(name)
            return retval
        return wrapper
    return inner

@profileit("profile_for_func1_001")
def func1(...)
    ...
Run Code Online (Sandbox Code Playgroud)

它看起来很复杂,但如果你一步一步地遵循它(并注意调用探查器的区别),它应该变得清晰.

  • 你怎么读`.profile`文件?它似乎不是文字. (6认同)

Ioa*_*ucu 11

装饰器看起来像:

import time
import logging

def profile(func):
    def wrap(*args, **kwargs):
        started_at = time.time()
        result = func(*args, **kwargs)
        logging.info(time.time() - started_at)
        return result

    return wrap

@profile
def foo():
    pass
Run Code Online (Sandbox Code Playgroud)

无论如何,如果你想做一些严肃的分析,我会建议你使用profile或cProfile包.

  • 问这不是什么?他从未问过时间问题.他确实询问过剖析. (2认同)

siw*_*sam 5

我喜欢@detly的回答。但有时使用SnakeViz查看结果会出现问题。

我制作了一个略有不同的版本,将结果作为文本写入同一文件:

import cProfile, pstats, io

def profileit(func):
    def wrapper(*args, **kwargs):
        datafn = func.__name__ + ".profile" # Name the data file sensibly
        prof = cProfile.Profile()
        retval = prof.runcall(func, *args, **kwargs)
        s = io.StringIO()
        sortby = 'cumulative'
        ps = pstats.Stats(prof, stream=s).sort_stats(sortby)
        ps.print_stats()
        with open(datafn, 'w') as perf_file:
            perf_file.write(s.getvalue())
        return retval

    return wrapper

@profileit
def function_you_want_to_profile(...)
    ...
Run Code Online (Sandbox Code Playgroud)

我希望这可以帮助别人...