【问题标题】:How to print absolute line number in uncaught exception?如何在未捕获的异常中打印绝对行号?
【发布时间】:2012-06-12 03:21:00
【问题描述】:

当发生错误时,Python 会打印如下内容:

Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "<stdin>", line 8, in m
  File "<stdin>", line 5, in exec_st
  File "<stdin>", line 9, in exec_assign
  File "<stdin>", line 48, in ref_by_id
IndexError: list index out of range

其中 2, ... , 48 是相对行号,不太方便。如何在此类错误消息中打印绝对行号?

编辑: 也许这是一个愚蠢的问题,但回答会促进一点发展。 我在几个文件中打印文本。完成后,按下运行 python 并将当前文件内容复制到控制台的快捷方式。建议的解决方案强制按下多余的按键(Ctrl+S、Alt+Tab)并创建其他文件。我希望我已经说清楚了。

【问题讨论】:

  • 从文件中运行程序,而不是在控制台输入或通过管道输入?
  • 谢谢,但我也想要程序化解决方案。
  • 也许你可以扩展你的问题一些?我不清楚绝对/相对行号是什么意思。我只是对上面的所有"&lt;stdin&gt;"s 感到困惑。你想做什么,为什么?特别是,反对从磁盘文件运行您的程序(我认为这会解决您的问题)是什么?
  • 这看起来有点相关:stackoverflow.com/questions/1278705/…
  • 也许您可以向我们展示您输入的(非常简化的)版本、您获得的实际输出以及您想要获得的内容?

标签: python debugging exception


【解决方案1】:

几分钟的修改让我在 Python 2.7 中得到了这个 Read-Eval-Print Loop:

#!/usr/bin/env python
import code
import sys

LINE_NUMBER=0

def reset_linenum():
    global LINE_NUMBER
    LINE_NUMBER=-1

def resettable_REPL():
    global LINE_NUMBER
    BUFFERED_LINES=[]
    ii=code.InteractiveInterpreter({"reset_linenum":reset_linenum})
    while True:
        try:
            BUFFERED_LINES.append(raw_input("!"+sys.ps1)+'\n')
            while (BUFFERED_LINES[-1][:1] in " \t" or
                   ii.runsource("\n"*LINE_NUMBER+"".join(BUFFERED_LINES), "console")):
                BUFFERED_LINES.append(raw_input("!"+sys.ps2)+'\n')
            LINE_NUMBER+=len(BUFFERED_LINES)
            BUFFERED_LINES=[]
        except EOFError:
            break

if __name__=='__main__':
    resettable_REPL()

这有点骇人听闻,但它会在会话继续时跟踪行号,并允许通过调用 reset_linenum() 来重置当前计数。一个示例会话:

!!!> print "hello"              # line 1
hello
!!!> def badfunc():             # line 2
!...     raise Exception("doh") # line 3
!!!> badfunc()                  # line 4
Traceback (most recent call last):
  File "console", line 4, in <module>
  File "console", line 3, in badfunc
Exception: doh
!!!> ?                          # line 5
  File "console", line 5
    ?
    ^
SyntaxError: invalid syntax
!!!> reset_linenum()            # RESET
!!!> raise Exception("!")       # line 1
Traceback (most recent call last):
  File "console", line 1, in <module>
Exception: !
!!!> 

编辑:修复了 REPL 不会过早地执行缩进块。

【讨论】:

  • 超级!虽然它有点错误和矫枉过正,我认为。 ` !!!> # unique string id !!!> def usid(): !... global Uid !!!> Uid += 1 File "", line None SyntaxError: unexpected indent (console, line 4 ) !!!> return str(Uid) # File "", line None SyntaxError: unexpected indent (console, line 5)`
  • 是的,在初次发布后发现了这个问题。现在试试?
  • 它有效。如果没有人会发布更“轻量级”的答案,我会接受这个。
【解决方案2】:

在 Linux 上执行此操作?与其让你的热键直接调用 python,不如让它调用这个 shell 脚本:

#!/bin/bash
cat > /tmp/$$.py
/usr/bin/env python /tmp/$$.py
rm -f $$.py

您也可以尝试(甚至可以在 Windows 上工作):

import sys
exec(compile("".join([line for line in sys.stdin]), "console", "single"))

【讨论】:

  • 如何从输入退出到“编译”? Ctrl+D 打印“^D”,Ctrl+C 打印“Traceback(最近一次调用最后一次):文件“”,第 1 行,在 KeyboardInterrupt”
  • 这是 Ctrl+Z 热键。但不幸的是,第二个 sn-p 不能正常工作。
  • 耸耸肩 矫枉过正?杀戮?一种更简单的方法,相应的功能更少
猜你喜欢
  • 2011-03-05
  • 2015-10-28
  • 2015-06-10
  • 2011-07-14
  • 2010-09-12
  • 2015-03-16
  • 1970-01-01
  • 2011-08-20
  • 2023-03-17
相关资源
最近更新 更多