关于python:打印一条错误消息而不打印回溯,当条件不满足时关闭程序

Print an error message without printing a traceback and close the program when a condition is not met

我看到过类似的问题,但没有一个真正解决的轨迹。如果我有这样的课

1
2
3
4
5
6
7
8
9
10
11
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"

我希望我的执行方法能够做到的是,如果我自己。_那么不等于字符串"then"(在allcaps中),那么我希望它引发一个自定义错误消息并终止整个程序,同时也不显示回溯。

如果遇到错误,唯一应该打印出来的东西看起来像(我以3为例,格式化不是问题)这一点。

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

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


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

Python 2 x

1
2
import sys
sys.tracebacklimit = 0

Python 3 x

在python 3.5.2和3.6.1中,将tracebacklimit设置为0似乎没有预期的效果。这是一个已知的错误。注意,-1也不起作用。然而,将其设置为None似乎确实有效,至少目前如此。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
>>> 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

然而,无论好坏,如果引发多个异常,它们都可以打印出来。例如:

1
2
3
4
5
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>

您可以使用try:,然后使用except Exception as inst:。将要做的是在名为inst的变量中给出错误消息,并且可以用inst.args打印出错误的参数。试着打印出来看看会发生什么,你要找的是inst.args中的任何项目吗?

编辑下面是我尝试的一个例子:Python闲置:

1
2
3
4
5
6
7
8
9
10
11
12
13
>>> 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和error,也可以使用sys.exit()


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

您可以实现一个接受typevaluetraceback的三参数函数,并执行您喜欢的任何操作(例如,只打印值)并将该函数分配给sys.excepthook

下面是一个例子:

1
2
3
4
5
6
7
8
import sys

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

sys.excepthook = excepthook

raise ValueError('hello')

这在python2和python3中都可用。


如果您想消除海关例外的任何追溯,并有行号,你可以做这个把戏

Python 3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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关键字无效

1
MyNewError (line 16): Now TraceBack Is Gone


一般来说,如果您想要捕获除SystemExit之外的任何异常,并在不进行回溯的情况下使用异常的消息退出,请定义您的main函数,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
>>> 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

请注意,在引发多个异常的情况下,只会打印一条消息。

这个答案是为了改进这个问题。