我想使用优秀的line_profiler,但只是在某些时候。为了使它工作,我添加
@profile
每次函数调用之前,例如
@profile
def myFunc(args):
blah
return
并执行
kernprof.py -l -v mycode.py args
但是我不想每次都手动放置@profile
装饰器,因为大多数时候我想要在没有它们的情况下执行代码,如果我试图包含它,我会得到一个例外他们,例如
mycode.py args
是否有一个快乐的媒介,我可以根据某些条件切换/参数动态删除装饰器,而不必手动操作和/或修改每个函数太多?
答案 0 :(得分:17)
不是删除 @profile
装饰线,而是提供您自己的传递无操作版本。
您可以将以下代码添加到项目的某个位置:
import __builtin__
try:
__builtin__.profile
except AttributeError:
# No line profiler, provide a pass-through version
def profile(func): return func
__builtin__.profile = profile
使用@profile
装饰器在任何代码之前导入此代码,您可以使用带或不带有行分析器的代码。
因为虚拟装饰器是一个传递函数,所以执行性能不会受到影响(只有导入性能每个轻微的受影响)。
如果您不喜欢搞乱内置插件,可以将它作为一个单独的模块;说profile_support.py
:
import __builtin__
try:
profile = __builtin__.profile
except AttributeError:
# No line profiler, provide a pass-through version
def profile(func): return func
(没有赋值到__builtin__.profile
)并在使用from profile_support import profile
装饰器的任何模块中使用@profile
。
答案 1 :(得分:4)
您根本不需要导入__builtins__
/ builtins
或LineProfiler
,在尝试查找NameError
时,您只需依靠profile
:
try:
profile
except NameError:
profile = lambda x: x
但是,这需要包含在使用profile
的每个文件中,但它不会(永久地)改变Python的全局状态(内置)。
答案 2 :(得分:3)
评论越来越成为@Martijin Pieters的变种。
我宁愿不涉及__builtin__
。没有评论,其他人几乎不可能猜到line_profiler
是否涉及,而且先验知道这一点。
查看kernprof
line 199,即可实例化LineProfiler
。
try:
from line_profiler import LineProfiler
profile = LineProfiler()
except ImportError:
def profile(func):
return func
导入(显式)is better而非全局修改builtins
(隐式)。如果剖析装饰器是永久性的,那么它们的原点应该在代码本身中清楚。
在line_profiler
出现时,无论是否由kernprof
运行,上述方法都会在每次运行时使用分析器包装装饰函数。这种副作用可能是不希望的。
答案 3 :(得分:1)
我在Python 3.4中使用以下修改版本
try:
import builtins
profile = builtins.__dict__['profile']
except KeyError:
# No line profiler, provide a pass-through version
def profile(func): return func