Python中有条件评估的调试语句 [英] Conditionally evaluated debug statements in Python
问题描述
Python有几种打印跟踪"输出的方法. print
, import logging
, stdout.write
可以用于打印调试信息,但是它们都有一个缺点:即使记录器的阈值是太高或流被关闭,Python仍将评估print语句的参数.(严格评估)这可能会花费字符串格式或更多的字符串格式.
Python has a few ways of printing "trace" output. print
, import logging
, stdout.write
can be used to print debugging info, but they all have one drawback: even if the logger's threshold is too high or the stream is closed, Python will still evaluate the arguments to the print statement. (Strict Evaluation) This could cost a string format or more.
最明显的解决方法是将创建字符串的代码放入lambda,并使用我们自己的日志记录功能有条件地调用lambda(此代码检查 __ debug __
内置变量,该变量设置为False每当python以 -O
启动以进行优化时):
The obvious fix is to put the string-creating code into a lambda, and use our own logging function to call the lambda conditionally (this one checks the __debug__
builtin variable, which is set to False whenever python is started with -O
for optimizations) :
def debug(f):
if __debug__:
print f()
#stdout.write(f())
#logging.debug(f())
for currentItem in allItems:
debug(lambda:"Working on {0}".format(currentItem))
优点是不会在发行版中调用 str(currentItem)
和 string.format
,缺点是必须输入 lambda:
在每个日志记录语句上.
The advantage is not calling str(currentItem)
and string.format
in release builds, and the disadvantage is having to type in lambda:
on every logging statement.
Python的 assert
语句.如果python是用 -O
运行的,那么所有assert语句都将被丢弃,而不会进行任何评估.您可以利用它来编写另一个条件评估的日志记录语句:
Python's assert
statement is treated specially by the Python compiler. If python is run with -O
, then any assert statements are discarded without any evaluation. You can exploit this to make another conditionally-evaluated logging statement:
assert(logging.debug("Working on {0}".format(currentItem)) or True)
使用 -O
启动Python时,不会评估此行.
This line will not be evaluated when Python is started with -O
.
甚至可以使用短路运算符'and'和'or':
The short-circuit operators 'and' and 'or' can even be used:
__debug__ and logging.debug("Working on {0}".format(currentItem));
但是现在我们最多可以包含28个字符以及输出字符串的代码.
But now we're up to 28 characters plus the code for the output string.
我要解决的问题:是否有任何标准的python语句或函数具有与 assert
语句相同的条件评估属性?或者,有人可以替代这里介绍的方法吗?
The question I'm getting to: Are there any standard python statements or functions that have the same conditional-evaluation properties as the assert
statement? Or, does anyone have any alternatives to the methods presented here?
推荐答案
我不知道在没有处理程序的情况下,对 logging.debug
的调用会影响性能多少.
I wonder how much a call to logging.debug
impacts the performance when there are no handlers.
但是 if __debug __:
语句仅被评估一次,即使在函数体内也是如此
However the if __debug__:
statement is evaluated only once, even in the body of a function
$ python -O
Python 2.6.6 (r266:84292, Dec 26 2010, 22:31:48)
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import dis
>>> import logging
>>> def debug(*a, **kw):
... if __debug__:
... logging.debug(*a, **kw)
...
>>> dis.dis(debug)
2 0 LOAD_CONST 0 (None)
3 RETURN_VALUE
>>>
,记录器可以使用字符串格式运算符为您格式化消息.这是从 logging.debug文档
and the logger can format the message for you using the string formatting operator. Here a slightly modified example taken from the logging.debug documentation
FORMAT = '%(asctime)-15s %(clientip)s %(user)-8s %(message)s'
logging.basicConfig(format=FORMAT)
d = { 'clientip' : '192.168.0.1', 'user' : 'fbloggs' }
debug('Protocol problem: %s', 'connection reset', extra=d)
在这种情况下,如果关闭优化,则永远不会评估消息字符串.
In this case the message string is never evaluated if the optimizations are turned off.
这篇关于Python中有条件评估的调试语句的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!