我一直在尝试在包装函数上使用
line_profiler
。但是,分析的是包装器函数而不是包装函数。下面的可执行代码片段显示我可以看到我的 @decorate
包装函数而不是我的 d()
函数被分析。
片段:testy_profiler.py
from line_profiler import LineProfiler
def a():
print("a")
from functools import wraps
def decorate(func):
@wraps(func)
def wrapper(*args, **kwargs):
r = func(*args, **kwargs)
print("decorating")
return r
return wrapper
@decorate
def d():
print("d")
def go():
a()
d()
lprofiler = LineProfiler()
lprofiler.add_function(a)
lprofiler.add_function(d)
lp_wrapper = lprofiler(go)
lp_wrapper()
lprofiler.print_stats()
输出:
$ python test_profiler.py
a
d
decorating
Timer unit: 1e-07 s
Total time: 1e-05 s
File: C:\Users\RENARDCH\Workspace\testy_profiler\test_profiler.py
Function: a at line 3
Line # Hits Time Per Hit % Time Line Contents
==============================================================
3 def a():
4 1 100.0 100.0 100.0 print("a")
Total time: 4.4e-06 s
File: C:\Users\RENARDCH\Workspace\testy_profiler\test_profiler.py
Function: wrapper at line 8
Line # Hits Time Per Hit % Time Line Contents
==============================================================
8 @wraps(func)
9 def wrapper(*args, **kwargs):
10 1 24.0 24.0 54.5 r = func(*args, **kwargs)
11 1 18.0 18.0 40.9 print("decorating")
12 1 2.0 2.0 4.5 return r
Total time: 1.87e-05 s
File: C:\Users\RENARDCH\Workspace\testy_profiler\test_profiler.py
Function: go at line 19
Line # Hits Time Per Hit % Time Line Contents
==============================================================
19 def go():
20 1 126.0 126.0 67.4 a()
21 1 61.0 61.0 32.6 d()
当两个函数用同一个包装器包装时,这尤其会带来问题,因为将为包装器生成全局分析,而不是单独为每个函数生成分析。
line_profiler
版本是3.4.0
绕过是让
d()
调用一个非包装函数,实际上完成这项工作,并分析这个子函数而不是d()
。
[...]
@decorate
def d():
effective_d()
def effective_d():
print("d")
[...]
lprofiler.add_function(effective_d)
[...]