我最近用 Python 编写了很多代码。我一直在处理以前从未使用过的数据,使用以前从未见过的公式并处理巨大的文件。 所有这些让我写了很多打印语句来验证一切是否正常并找出故障点。但是,一般来说,输出如此多的信息并不是一个好的做法。如何仅在我想要调试时使用打印语句,并在我不想打印它们时跳过它们?
logging
模块拥有您想要的一切。一开始可能看起来有些多余,但只使用您需要的部分。我建议使用 logging.basicConfig
设置日志记录级别,然后使用简单的日志方法:debug
、info
、warning
、error
和 critical
。
import logging
logging.basicConfig(level=logging.DEBUG)
logging.debug('A debug message!')
logging.info('We processed %d records', len(processed_records))
执行此操作的一个简单方法是调用日志记录函数:
DEBUG = True
def log(s):
if DEBUG:
print s
log("hello world")
然后您可以更改
DEBUG
的值并在带或不带日志记录的情况下运行代码。
logging
模块对此有更精细的机制。
使用logging内置库模块而不是打印。
您创建一个
Logger
对象(例如 logger
),然后,每当您插入调试打印时,只需输入:
logger.debug("Some string")
您可以在程序开始时使用
logger.setLevel
设置输出电平。如果将其设置为 DEBUG,它将打印所有调试信息。将其设置为 INFO 或更高,所有调试将立即消失。
您还可以使用它在不同级别(信息、警告和错误)记录更严重的事情。
首先,我将支持 python 的 logging 框架的提名。 但是,请注意如何使用它。 具体来说:让日志框架扩展您的变量,而不是您自己这样做。 例如,而不是:
logging.debug("datastructure: %r" % complex_dict_structure)
确保你这样做:
logging.debug("datastructure: %r", complex_dict_structure)
因为虽然它们看起来很相似,但第一个版本会产生 repr() 成本即使它被禁用。 第二个版本避免了这种情况。 同样,如果你自己推出,我建议类似:
def debug_stdout(sfunc):
print(sfunc())
debug = debug_stdout
通过以下方式调用:
debug(lambda: "datastructure: %r" % complex_dict_structure)
如果您通过以下方式禁用它,这将再次避免开销:
def debug_noop(*args, **kwargs):
pass
debug = debug_noop
计算这些字符串的开销可能并不重要,除非它们 1)计算成本昂贵或 2)调试语句位于 n^3 循环或其他东西的中间。 并不是说我对此一无所知。
我不了解其他人,但我习惯于定义一个“全局常量”(
DEBUG
),然后定义一个全局函数(debug(msg)
),只有在msg
时才会打印DEBUG == True
。
然后我编写调试语句,例如:
debug('My value: %d' % value)
...然后我选择了单元测试并且再也没有这样做过! :)
调试代码的更好方法是使用模块 clrprint
仅当传递参数 debug=True 时才打印彩色全输出
from clrprint import *
clrprint('ERROR:', information,clr=['r','y'], debug=True)