今天我在想一个我在一年前写的Python项目,我用logging
得非常广泛.我记得由于开销(hotshot
表明它是我最大的瓶颈之一),必须在类似内循环的场景(90%代码)中注释掉大量的日志调用.
我现在想知道是否有一些规范的方法可以在Python应用程序中以编程方式去除日志记录调用,而无需一直注释和取消注释.我认为您可以使用检查/重新编译或字节码操作来执行此类操作,并仅针对导致瓶颈的代码对象.这样,您可以添加操纵器作为后编译步骤并使用集中配置文件,如下所示:
[Leave ERROR and above] my_module.SomeClass.method_with_lots_of_warn_calls [Leave WARN and above] my_module.SomeOtherClass.method_with_lots_of_info_calls [Leave INFO and above] my_module.SomeWeirdClass.method_with_lots_of_debug_calls
当然,您希望谨慎使用它,并且可能只使用每个函数的粒度 - 仅适用于已显示logging
为瓶颈的代码对象.有人知道这样的事吗?
注意:由于动态类型和后期绑定,有一些因素使性能更难以执行.例如,对命名方法的任何调用都debug
可能必须用if not isinstance(log, Logger)
.在任何情况下,我都假设所有的细节都可以通过绅士的协议或一些运行时检查来克服.:-)
使用logging.disable怎么样?
我还发现如果日志消息的创建成本很高,我必须使用logging.isEnabledFor.
我也看到断言以这种方式使用.
assert logging.warn('disable me with the -O option') is None
(我猜警告总是不返回..如果没有,你会得到一个AssertionError
但实际上,这只是一种有趣的方式:
if __debug__: logging.warn('disable me with the -O option')
当您使用-O选项运行其中包含该行的脚本时,该行将从优化的.pyo代码中删除.相反,如果您拥有自己的变量,就像下面一样,您将拥有一个始终执行的条件(无论变量是什么值),尽管条件应该比函数调用执行得更快:
my_debug = True ... if my_debug: logging.warn('disable me by setting my_debug = False')
因此,如果我对调试的理解是正确的,那么它似乎是一种摆脱不必要的日志记录调用的好方法.另一方面,它还会禁用所有断言,因此如果需要断言则会出现问题.
使用pypreprocessor
也可以在PYPI(Python包索引)上找到,并使用pip获取.
这是一个基本的用法示例:
from pypreprocessor import pypreprocessor pypreprocessor.parse() #define nologging #ifdef nologging ...logging code you'd usually comment out manually... #endif
本质上,预处理器会按照您之前手动执行的方式注释代码.它只是根据您定义的条件有条不紊地进行.
您还可以通过在import和parse()语句之间添加'pypreprocessor.removeMeta = True'来删除所有预处理程序指令并从后处理代码中注释掉代码.
字节码输出(.pyc)文件将包含优化的输出.
SideNote:pypreprocessor与python2x和python3k兼容.
免责声明:我是pypreprocessor的作者.