【问题标题】:Python3: Is it possible to make a error not show the line of code that caused the error?Python3:是否有可能出错不显示导致错误的代码行?
【发布时间】:2022-01-21 07:09:01
【问题描述】:

我想知道是否有可能让回溯不显示导致错误的代码行。

我不想要:

>>> print("hi"f)
  File "<stdin>", line 1
    print("hi"f)
              ^
SyntaxError: invalid syntax

我确实想要:

>>> print("hi"f)
  File "<stdin>", line 1
SyntaxError: invalid syntax

【问题讨论】:

  • 您是否真的希望在 REPL 中输入您的代码时发生这种情况,就像您的示例显示的那样,或者它是用于磁盘上的模块,您可以在其中拥有一个 .pyo 文件,但是没有对应的.py?
  • 明确地说,这可能无论哪种方式 - 没有什么能阻止你编写自己的异常处理程序 - 但方法肯定有所不同。
  • 让你的软件以一种意想不到的方式运行通常是一个坏主意,尤其是如果它真的没有增加任何价值 - 如果你这样做是因为你需要对你的代码保密,你应该首先重新考虑使用 Python,因为无论如何您的代码都将与您的软件一起分发。如果您这样做是因为您想要更好的错误消息,请考虑捕获异常并编写更好的错误消息 - 或处理错误以便甚至不需要错误消息。
  • @Grismar 然后你可以编译成.pyc文件(如果你想要隐藏代码而这个问题只是一个答案)
  • 如果你只是分发一个.pyc(接受它只能在编译它的架构上运行并且只能在编译它的相同版本的 Python 上运行的事实),这个问题是没有意义的因为那样错误消息实际上正是您所要求的。 (当然,.pyc 反编译起来相当简单,但至少它保护了最初编写的代码——不管它得到什么)

标签: python traceback


【解决方案1】:

您可以通过使用tryexcept 来完全防止错误

try:
   print("hello"f)
except:
   print("found error");

现在,如您所见,第一行有一个错误,当 python 解释器发现该错误时,它不会调用回溯,而是运行except 块中的代码...

【讨论】:

  • 不,这只适用于运行时错误,它对 SyntaxError 没有用,因为实际上没有代码被执行。
  • 我正在寻找的是正常的错误消息,但没有显示导致问题的代码行。你的问题只是抑制了错误信息(同时"str"f 是一个未被try抑制的错误)
【解决方案2】:

我刚刚写了辅助函数ExcText(),你可以看看我是如何在test()函数中使用它的。如果您将其称为ExcText(False),则不会打印代码行,如果将其称为ExcText(True),则会打印它们。

Try it online!

def ExcText(show_lines):
    import sys, traceback
    r = traceback.StackSummary.extract(traceback.walk_tb(sys.exc_info()[2]))
    if not show_lines:
        for i, e in enumerate(r):
            r[i]._line = ''
    return ''.join(['Traceback (most recent call last):\n'] + r.format() +
        traceback.format_exception_only(*sys.exc_info()[:2]))

def test():
    try:
        def g():
            assert False, 'Hello, World!'
        def f():
            g()
        f()
    except:
        print(ExcText(False))

test()

ExcText(False) 的输出:

Traceback (most recent call last):
  File "C:\t\test.py", line 16, in test
  File "C:\t\test.py", line 15, in f
  File "C:\t\test.py", line 13, in g
AssertionError: Hello, World!

ExcText(True) 的输出:

Traceback (most recent call last):
  File "C:\t\test.py", line 16, in test
    f()
  File "C:\t\test.py", line 15, in f
    g()
  File "C:\t\test.py", line 13, in g
    assert False, 'Hello, World!'
AssertionError: Hello, World!

您也可以使用上面的代码来捕获语法错误,只需执行compile(program_text, '&lt;string&gt;', 'exec'),其中程序文本是包含需要检查的脚本文本的字符串,例如code is here。您还可以通过以下方式从文件中读取程序文本:

with open(filename, 'r', encoding = 'utf-8') as f:
    prog = f.read()

当你只需要语法检查时,你应该使用compile()而不是exec(),因为脚本(程序文本)可能包含一些恶意代码(如木马),exec()会在检查语法后执行它,而@987654339 @ 不会执行,只是检查它是否可编译并且没有语法错误。


也可以通过修改linecache.getline()函数来实现代码行的不打印,如下所示。

但请注意,此解决方案会修改标准模块,因此应尽可能避免这种 hack。上面的第一个解决方案更好。

Try it online!

def test():
    import traceback
    traceback.linecache.getline = lambda *pargs, **nargs: ''
    
    try:
        def g():
            assert False, 'Hello, World!'
        def f():
            g()
        f()
    except:
        traceback.print_exc()

test()

输出:

Traceback (most recent call last):
  File "C:\t\test.py", line 10, in test
  File "C:\t\test.py", line 9, in f
  File "C:\t\test.py", line 7, in g
AssertionError: Hello, World!

【讨论】:

  • 没关系,但对语法错误不起作用。够好了!
  • @Allearthstuffs 也可以捕获语法错误我写了example here,注意,我使用了print(ExcText(False, True)),也试试ExcText(False, False)
  • @Allearthstuffs 在前面的评论中我使用prog = '''...'''作为代码内的内联字符串,你也可以从文本文件中读取它为prog = open(filename, encoding = 'utf-8').read()
  • @Allearthstuffs 如果我的回答是正确的和/或有帮助的,请不要忘记接受和/或支持它。接受和投票是在我对左侧答案的顶部完成的,有向上箭头(上三角形)表示接受投票,复选标记表示接受。接受意味着正确的答案可以解决您的任务。 UpVoting 表示您喜欢这个答案。 UpVoting 和 Accepting 都可以同时完成,它们都给我(答案的作者)额外的分数以提高我的声誉。
  • 好吧,我想这是不可能的(编辑:可能来自@Charles Duffy 对问题的评论)避免 all 行不显示,因为你的代码在website (它的输出 [thats on the website]) (error message) 不显示函数名称但确实显示print(f')
猜你喜欢
  • 2012-06-02
  • 2012-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-11
  • 1970-01-01
  • 2020-06-20
  • 1970-01-01
相关资源
最近更新 更多