如何在不注释Python日志调用的情况下删除它们?

2024-05-17 00:59:26 发布

您现在位置:Python中文网/ 问答频道 /正文

今天我在想一个一年前写的Python项目,在那里我广泛地使用了logging。我记得在类似内环的场景(90%的代码)中不得不注释掉很多日志调用,因为开销太大(hotshot表明这是我最大的瓶颈之一)。

我现在想知道是否有某种规范的方法可以在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)包装。无论如何,我想所有的小细节都可以通过一个绅士协议或者一些运行时检查来解决。:-)


Tags: andof方法代码myloggingwith方式
3条回答

我也见过assert以这种方式使用。

assert logging.warn('disable me with the -O option') is None

(我猜warn总是返回none。。如果没有,你会得到一个断言者

但实际上这只是一种有趣的方式:

if __debug__: logging.warn('disable me with the -O option')

当您使用-O选项运行包含该行的脚本时,该行将从optimized.pyo代码中删除。相反,如果您有自己的变量,如下面所示,那么您将有一个始终执行的条件(无论变量的值是什么),尽管条件的执行速度应该比函数调用快:

my_debug = True
...
if my_debug: logging.warn('disable me by setting my_debug = False')

因此,如果我对调试的理解是正确的,那么这似乎是摆脱不必要的日志记录调用的好方法。另一方面,它也会禁用所有断言,因此,如果需要这些断言,这是一个问题。

使用logging.disable怎么样?

我还发现,如果日志消息的创建成本很高,则必须使用logging.isEnabledFor

使用pypreprocessor

也可以在PYPI (Python Package Index)上找到,并使用pip获取。

下面是一个基本用法示例:

from pypreprocessor import pypreprocessor

pypreprocessor.parse()

#define nologging

#ifdef nologging
...logging code you'd usually comment out manually...
#endif

从本质上讲,预处理器按照您以前手动执行的方式注释掉代码。它只是根据你的定义有条件地运行。

您还可以通过在导入和之间添加“pypreprocessor.removeMeta=True”从后处理代码中删除所有预处理器指令并注释掉代码 parse()语句。

字节码输出(.pyc)文件将包含优化的输出。

注:pypreprocessor与python2x和python3k兼容。

免责声明:我是pypreprocessor的作者。

相关问题 更多 >