Распечатайте сообщение об ошибке без печати обратной трассировки и закройте программу, если условие не выполнено

Я видел подобные вопросы к этому, но ни один из них не обращается к треку. Если у меня такой класс

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"

то, что я хочу, чтобы мой метод execute мог сделать, это если self._then не равен строке "THEN" (в allcaps), тогда я хочу, чтобы она вызвала пользовательское сообщение об ошибке и завершила всю программу, а также не показывала обратную трассировку.

Если ошибка обнаружена, единственное, что должно распечатать, будет выглядеть примерно так (я использую 3 например, форматирование не является проблемой).

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

Я не очень разборчив в том, что на самом деле это объект класса исключений, поэтому в этом аспекте нет проблем. Поскольку я буду использовать это в цикле while, simple if, elif просто повторяет сообщение снова и снова (потому что, очевидно, я не закрываю цикл). Я видел сис.exit (), но это также печатает гигантский блок красного текста, если я не использую его правильно. Я не хочу ловить исключение в моем цикле, потому что в том же модуле есть другие классы, в которых мне нужно реализовать что-то вроде этого.

5 ответов


можно использовать try: а то except Exception as inst: Это даст вам сообщение об ошибке в переменной с именем inst, и вы можете распечатать аргументы об ошибке с помощью inst.args. Попробуйте распечатать его и посмотреть, что произойдет, и любой элемент inst.args - Это тот, который вы ищете.

EDIT вот пример, который я пробовал с pythons 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'
>>> 

EDIT 2: Что касается закрытия программы, вы всегда можете raise и ошибок или вы можете использовать sys.exit()


вы можете отключить трассировку, ограничив ее глубину.

Python 2.x

import sys
sys.tracebacklimit = 0

Python 3.x

в Python 3.5.2 и 3.6.1, задание tracebacklimit to 0 похоже, не имеет предполагаемого эффекта. Это известный ошибка. Обратите внимание, что -1 не работает. Установка его в None однако, похоже, работает, по крайней мере, на данный момент.

>>> 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

тем не менее, к лучшему или худшему, если несколько исключений подняты, их все еще можно напечатать. Например:

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>

самый чистый способ, который я знаю, это использовать 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.


Если вы хотите избавиться от каких-либо traceback для таможенных исключений и иметь номер строки, вы можете сделать этот трюк

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 ключевое слово useless

MyNewError (line 16): Now TraceBack Is Gone

В общем, если вы хотите, чтобы поймать любое исключение, кроме 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

обратите внимание, что в случае возникновения нескольких исключений печатается только одно сообщение.

этот ответ предназначен для улучшения один за-это.