【问题标题】:python - is there no better way to get the expression in a debug functionpython - 没有更好的方法来获取调试函数中的表达式
【发布时间】:2011-12-20 09:09:01
【问题描述】:

在 c 代码中我经常使用 printf 调试宏,例如

#define DPRINT_INT(i) fprintf(stderr,"%s has the value %i at line %i", #i,i, __LINE__)

然后我可以做类似的事情 DPRINT_INT(高度) 它将在哪里打印变量或类似的东西 DPRINT_INT(from_cm_to_inch(get_average(heights))) 它会打印出名称的整个表达式。

要为 python 执行此操作,因为 python 没有类似 c 的宏

我传递一个字符串并使用检查来获取调用函数环境以调用 eval。 但我不喜欢传递字符串,它丑陋且容易忘记(我让它检查类型并在传递非字符串时调用异常)并且在 ide 中效果不佳。

没有办法从调试函数的python代码中提取变量名和表达式吗?有吗?

【问题讨论】:

  • 在 Python 中,我们倾向于将我们可以 unittest 和/或 import 的模块写入 REPL 并在必要时将它们驱动到那里。在五年的 Python 编程中,我从未使用过调试器。
  • 我不是在谈论调试器,尽管 ipython -pdb 很好(ipython 中的异常调试器)。我说的是 printf 调试,即将 debug_print 函数洒在程序中的点上,将其视为日志记录的快速而肮脏的替代方案
  • 在这里同意 Johnsyweb:只需输入一些 logging.debug 声明即可。模块的导入和配置只有两行,此外它还为您提供了以后轻松禁用日志级别而无需更改代码的好处。

标签: python debugging macros abstract-syntax-tree printf-debugging


【解决方案1】:

在 Python 中,我们倾向于编写可以unittest 和/或导入到 REPL 中的模块,并在必要时将它们驱动到那里。

如果您可以对函数进行单元测试,则可以证明它们在任何给定输入下的行为。但是,如果必须编写调试语句,则应使用标准 logging 模块中的 debug()

例如:

#!/usr/bin/env python

import logging
import inspect

def buggy_fn():
    d = 42;
    if d != 69:
        logging.debug('%s(%d): %s is not what we expected. [%s]',
                inspect.currentframe().f_back.f_code.co_filename,
                inspect.currentframe().f_back.f_lineno,
                'd',
                repr(d),
                )

if __name__ == '__main__':
    logging.basicConfig(level=logging.DEBUG)
    buggy_fn()

将输出...

DEBUG:root:./buggy.py(19): d is not what we expected. [42]

inspect 中有很多有用的东西可以在你需要的时候帮助你。

【讨论】:

  • 有没有办法让它捕获变量名/表达式并打印出来?因为这是我的主要目标
  • Johnsyweb 有什么方法可以捕获除字符串/eval 之外的 d/变量名称/表达式名称吗?(所以您不必重复它?)。也许我应该只实现一个子类或包含/转发到记录器的 Eval Log 类?
  • 大部分事情都可以在 Python 中实现。不过,它们并不总是一个好主意。请参阅this answerHow can you print a variable name in python?
猜你喜欢
  • 1970-01-01
  • 2014-05-14
  • 2015-08-22
  • 2010-11-11
  • 2023-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多