仅使用print语句进行调试

cra*_*liv 100 python

我最近在Python中编写了大量代码.我一直在处理以前没有使用过的数据,使用以前从未见过的公式和处理大文件.所有这些让我写了很多印刷语句来验证它是否一切顺利并确定失败点.但是,一般来说,输出如此多的信息并不是一种好的做法.如果我想调试时如何使用print语句,当我不希望它们被打印时让它们被跳过?

Mat*_*ner 150

logging模块拥有您想要的一切.一开始可能看起来过多,但只使用您需要的部件.我推荐使用logging.basicConfig切换日志级别stderr简单的日志方法,debug,info,warning,errorcritical.

import logging, sys
logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
logging.debug('A debug message!')
logging.info('We processed %d records', len(processed_records))
Run Code Online (Sandbox Code Playgroud)

  • 另外,如果你像我一样在安装这个模块时遇到问题;日志记录是标准库的一部分 - 即使使用虚拟环境也不需要安装 pip (7认同)
  • 恐怕这在 jupyter lab 1.2.6 上不起作用。您可以设置一次日志记录级别,使用“logging.basicConfig(stream=sys.stderr, level=logging.ERROR)”重新设置将无效。重新启动内核并设置新级别是可行的,但这对我来说是一个解决方法。 (2认同)

Gre*_*ill 26

一种简单的方法是调用日志记录功能:

DEBUG = True

def log(s):
    if DEBUG:
        print s

log("hello world")
Run Code Online (Sandbox Code Playgroud)

然后,您可以更改值的值,DEBUG并在有或没有日志记录的情况下运行代码.

标准logging模块具有更精细的机制.

  • 没错,但值得了解一个人如何*自己动手. (9认同)
  • 从长远来看,使用提供的[logging](http://docs.python.org/library/logging.html)模块可能比滚动自己更好(尽管它看起来更复杂). (4认同)

mgi*_*uca 20

使用日志记录内置库模块而不是打印.

你创建一个Logger对象(比方说logger),然后在你插入调试打印后,你只需要:

logger.debug("Some string")
Run Code Online (Sandbox Code Playgroud)

您可以logger.setLevel在程序开头使用来设置输出级别.如果将其设置为DEBUG,它将打印所有调试.将其设置为INFO或更高,并立即所有调试将消失.

您还可以使用它来记录不同级别的更严重的事情(INFO,WARNING和ERROR).


pjz*_*pjz 9

首先,我将提名python的日志框架.但是,要小心你如何使用它.具体来说:让日志框架扩展您的变量,不要自己动手.例如,而不是:

logging.debug("datastructure: %r" % complex_dict_structure)
Run Code Online (Sandbox Code Playgroud)

确保你这样做:

logging.debug("datastructure: %r", complex_dict_structure)
Run Code Online (Sandbox Code Playgroud)

因为虽然它们看起来很相似,但即使它被禁用,第一个版本也会产生repr()成本.第二个版本避免这种情况.同样,如果你自己滚动,我会建议:

def debug_stdout(sfunc):
    print(sfunc())

debug = debug_stdout
Run Code Online (Sandbox Code Playgroud)

通过:

debug(lambda: "datastructure: %r" % complex_dict_structure)
Run Code Online (Sandbox Code Playgroud)

如果您通过执行以下操作禁用它,它将再次避免开销:

def debug_noop(*args, **kwargs):
    pass

debug = debug_noop
Run Code Online (Sandbox Code Playgroud)

计算这些字符串的开销可能并不重要,除非它们要么计算成本高昂,要么2)调试语句位于例如n ^ 3循环或其他东西的中间.不是我会对此有所了解.


mac*_*mac 7

我不了解其他人,但我习惯于定义一个"全局常量"(DEBUG),然后是一个全局函数(debug(msg)),msg只有在打印时才会打印DEBUG == True.

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

debug('My value: %d' % value)
Run Code Online (Sandbox Code Playgroud)

...然后我接受单元测试,再也没有这样做过!:)

  • 我不想阻止单元测试——它是必不可少的。但我不认为它可以替代日志记录,即使作为一种调试技术。我仍然进行大量打印以快速测试事物。 (2认同)
  • @mac看起来你的链接现在需要一个明确的'www' - 它现在[托管在这里](http://www.diveintopython.net/unit_testing/index.html). (2认同)