打印错误消息而不打印回溯,并在不满足条件时关闭程序

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

我见过与此类似的问题,但没有一个真正解决引用问题。 如果我有这样的课程

class Stop_if_no_then():
    def __init__(self, value one, operator, value_two, then, line_or_label, line_number):
        self._firstvalue = value_one
        self._secondvalue = value_two
        self._operator = operator
        self._gohere = line_or_label
        self._then = then
        self._line_number = line_number

    def execute(self, OtherClass):
        "code comparing the first two values and making changes etc"

我希望我的执行方法能够做的是,如果 self._then 不等于字符串“THEN”(全部大写),那么我希望它引发自定义错误消息并终止整个程序,同时也不显示追溯。

如果遇到错误,唯一应该打印出来的内容将类似于(我使用 3 作为示例,格式不是问题)。

`Syntax Error (Line 3): No -THEN- present in the statement.`

我对它实际上是一个异常类对象不是很挑剔,所以在这方面没有问题。因为我将在 while 循环中使用它,所以简单的 if, elif 只是一遍又一遍地重复该消息(因为显然我没有关闭循环)。我见过 sys.exit() 但它也会打印出一大块红色文本,除非我没有正确使用它。我不想在循环中捕获异常,因为同一模块中还有其他类,我需要在其中实现类似的东西。

python exception error-handling customization traceback
8个回答
75
投票

您可以通过限制其深度来关闭回溯。

Python 2.x

import sys
sys.tracebacklimit = 0

Python 3.x

在Python 3.5.2和3.6.1中,将

tracebacklimit
设置为
0
似乎没有达到预期的效果。这是一个已知的bug。请注意,
-1
也不起作用。不过,将其设置为
None
似乎确实有效,至少目前如此。

在 Python 3.6.2 及更高版本中,您应该将

tracebacklimit
设置为
0
-1
,因为将其设置为
None
不会禁用回溯输出。

Python 3.6.1 及以下结果:

>>> import sys

>>> sys.tracebacklimit = 0
>>> raise Exception
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
Exception

>>> sys.tracebacklimit = -1
>>> raise Exception
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
Exception

>>> sys.tracebacklimit = None
>>> raise Exception
Exception

Python 3.6.2 及以上结果:

>>> import sys

>>> sys.tracebacklimit = 0
>>> raise Exception
Exception

>>> sys.tracebacklimit = -1
>>> raise Exception
Exception

>>> sys.tracebacklimit = None
>>> raise Exception
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
Exception

尽管如此,无论好坏,如果引发多个异常,它们仍然可以全部打印出来。例如:

socket.gaierror: [Errno -2] Name or service not known

During handling of the above exception, another exception occurred:

urllib.error.URLError: <urlopen error [Errno -2] Name or service not known>

37
投票

您可以使用

SystemExit
例外:

except Exception as err:
    raise SystemExit(err)

请参阅 有关

SystemExit
的文档了解更多详细信息。


18
投票

您可以使用

try:
,然后使用
except Exception as inst:
这样做的作用是在名为 inst 的变量中提供错误消息,并且您可以使用
inst.args
打印出错误的参数。尝试将其打印出来,看看会发生什么,
inst.args
中的任何一项都是您要查找的项。

编辑这是我尝试使用 python IDLE 的示例:

>>> try:
    open("epik.sjj")
except Exception as inst:
    d = inst


>>> d
FileNotFoundError(2, 'No such file or directory')
>>> d.args
(2, 'No such file or directory')
>>> d.args[1]
'No such file or directory'
>>> 

编辑2:至于关闭程序,您始终可以

raise
并出错,或者您可以使用
sys.exit()


15
投票

我知道的最干净的方法是使用

sys.excepthook

您实现一个三参数函数,它接受

type
value
traceback
并执行您喜欢的任何操作(例如,仅打印值)并将该函数分配给
sys.excepthook

这是一个例子:

import sys

def excepthook(type, value, traceback):
    print(value)

sys.excepthook = excepthook

raise ValueError('hello')

这在 python 2 和 python 3 中都可用。


9
投票

如果您想摆脱海关例外的任何追溯并拥有行号, 你可以做到这个技巧

Python 3

import sys
import inspect

class NoTraceBackWithLineNumber(Exception):
    def __init__(self, msg):
        try:
            ln = sys.exc_info()[-1].tb_lineno
        except AttributeError:
            ln = inspect.currentframe().f_back.f_lineno
        self.args = "{0.__name__} (line {1}): {2}".format(type(self), ln, msg),
        sys.exit(self)

class MyNewError(NoTraceBackWithLineNumber):
    pass

raise MyNewError("Now TraceBack Is Gone")

将给出此输出,并使

raise
关键字无用

MyNewError (line 16): Now TraceBack Is Gone

8
投票

“可以使用

from None
禁用异常链” - Python 文档

>>> try:
...     open('database.sqlite')
... except IOError:
...     raise RuntimeError from None

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>

3
投票

一般来说,如果您想捕获除

SystemExit
之外的任何异常,并退出并显示异常消息而不回溯,请定义您的
main
函数,如下所示:

>>> import sys

>>> def main():
...     try:
...         # Run your program from here.
...         raise RandomException  # For testing
...     except (Exception, KeyboardInterrupt) as exc:
...         sys.exit(exc)
... 
>>> main()
name 'RandomException' is not defined

$ echo $?
1

请注意,如果引发多个异常,则仅打印一条消息。

这个答案旨在改进 The-IT 的答案。


0
投票

traceback
模块与
limit=0
(或任何其他数字)一起使用

import traceback
try:
    1/0
except Exception as e:
    traceback.print_exception(e, limit=0)
© www.soinside.com 2019 - 2024. All rights reserved.