代码之家  ›  专栏  ›  技术社区  ›  detly

使用cprofile时返回值

  •  18
  • detly  · 技术社区  · 15 年前

    我正试图分析一个实例方法,所以我做了如下工作:

    import cProfile
    
    class Test():
    
        def __init__(self):
            pass
    
        def method(self):
            cProfile.runctx("self.method_actual()", globals(), locals())
    
        def method_actual(self):
            print "Run"
    
    if __name__ == "__main__":
        Test().method()
    

    但现在,当我希望“method”返回一个由“method_-actual”计算的值时,就会出现问题。我不想两次调用“method_-actual”。

    还有其他的方法吗,一些线程安全的方法?(在我的应用程序中,cprofile数据被保存到一个参数命名的数据文件中,这样它们就不会被删除,稍后我可以合并它们。)

    5 回复  |  直到 8 年前
        1
  •  32
  •   detly    15 年前

    我发现你可以做到:

    prof = cProfile.Profile()
    retval = prof.runcall(self.method_actual, *args, **kwargs)
    prof.dump_stats(datafn)
    

    缺点是它没有文件。

        2
  •  19
  •   wordsforthewise    8 年前

    任意代码的选项:

    import cProfile, pstats, sys
    pr = cProfile.Profile()
    pr.enable()
    
    my_return_val = my_func(my_arg)
    
    pr.disable()
    ps = pstats.Stats(pr, stream=sys.stdout)
    ps.print_stats()
    

    取自 https://docs.python.org/2/library/profile.html#profile.Profile

        3
  •  6
  •   Scott Stafford    12 年前

    我也遇到了同样的问题,并使用了一个包装函数来获取直接返回值。而不是

    cP.runctx("a=foo()", globals(), locales())
    

    我创建了一个包装函数

    def wrapper(b):
      b.append(foo())
    

    并分析对包装函数的调用

    b = []
    cP.runctx("wrapper(b)", globals(), locals())
    a = b[0]
    

    然后从输出参数(b)中提取foo的计算结果。

        4
  •  1
  •   HeyWatchThis    10 年前

    我想@detly the .runcall() 基本上是最好的答案,但为了完整性,我只想把@thomash的答案看作是功能独立的:

    def wrapper(b, f, *myargs, **mykwargs):
        try:
            b.append(f(*myargs, **mykwargs))
        except TypeError:
            print 'bad args passed to func.'
    
    # Example run
    def func(a, n):
        return n*a + 1
    
    b = []
    cProfile.runctx("wrapper(b, func, 3, n=1)", globals(), locals())
    a = b[0]
    print 'a, ', a
    
        5
  •  1
  •   Jonathan Hartley Zombie    9 年前

    我创造了一个装饰师:

    import cProfile
    import functools
    import pstats
    
    def profile(func):
    
        @functools.wraps(func)
        def inner(*args, **kwargs):
            profiler = cProfile.Profile()
            profiler.enable()
            try:
                retval = func(*args, **kwargs)
            finally:
                profiler.disable()
                with open('profile.out', 'w') as profile_file:
                    stats = pstats.Stats(profiler, stream=profile_file)
                    stats.print_stats()
            return retval
    
        return inner
    

    用它来装饰你的功能或方法:

    @profile
    def somefunc(...):
       ...
    

    现在,这个函数将被分析。

    或者,如果您想要原始的、未处理的配置文件数据(例如,因为您想在其上运行优秀的图形查看器runsnakerun),那么:

    import cProfile
    import functools
    import pstats
    
    def profile(func):
    
        @functools.wraps(func)
        def inner(*args, **kwargs):
            profiler = cProfile.Profile()
            profiler.enable()
            try:
                retval = func(*args, **kwargs)
            finally:
                profiler.disable()
                profiler.dump_stats('profile.out')
            return retval
    
        return inner
    

    这是对本页其他几个答案的微小改进。