仅使用打印语句进行调试

问题描述 投票:0回答:6

我最近用 Python 编写了很多代码。我一直在处理以前从未使用过的数据,使用以前从未见过的公式并处理巨大的文件。 所有这些让我写了很多打印语句来验证一切是否正常并找出故障点。但是,一般来说,输出如此多的信息并不是一个好的做法。如何仅在我想要调试时使用打印语句,并在我不想打印它们时跳过它们?

python
6个回答
221
投票

标准库中的

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))

46
投票

执行此操作的一个简单方法是调用日志记录函数:

DEBUG = True

def log(s):
    if DEBUG:
        print s

log("hello world")

然后您可以更改

DEBUG
的值并在带或不带日志记录的情况下运行代码。

标准

logging
模块对此有更精细的机制。


23
投票

使用logging内置库模块而不是打印。

您创建一个

Logger
对象(例如
logger
),然后,每当您插入调试打印时,只需输入:

logger.debug("Some string")

您可以在程序开始时使用

logger.setLevel
设置输出电平。如果将其设置为 DEBUG,它将打印所有调试信息。将其设置为 INFO 或更高,所有调试将立即消失。

您还可以使用它在不同级别(信息、警告和错误)记录更严重的事情。


15
投票

首先,我将支持 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 循环或其他东西的中间。 并不是说我对此一无所知。


7
投票

我不了解其他人,但我习惯于定义一个“全局常量”

DEBUG
),然后定义一个全局函数(
debug(msg)
),只有在
msg
时才会打印
DEBUG == True

然后我编写调试语句,例如:

debug('My value: %d' % value)

...然后我选择了单元测试并且再也没有这样做过! :)


1
投票

调试代码的更好方法是使用模块 clrprint

仅当传递参数 debug=True 时才打印彩色全输出

from clrprint import *
clrprint('ERROR:', information,clr=['r','y'], debug=True)
© www.soinside.com 2019 - 2024. All rights reserved.