web-dev-qa-db-ja.com

トレースバックを印刷せずにエラーメッセージを印刷し、条件が満たされない場合はプログラムを閉じます

私はこれと同様の質問を見たことがありますが、実際にトラックバックに対処する質問はありません。こんなクラスがあると

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"(allcaps内)と等しくない場合、カスタムエラーメッセージを生成してプログラム全体を終了させ、トレースバックも表示しないようにすることです。 。

エラーが発生した場合、印刷する必要があるのは次のようになります(例として3を使用していますが、フォーマットは問題ありません)。

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

私はそれが実際には例外クラスのオブジェクトであることについてあまり気にしないので、その点で問題はありません。これをwhileループで使用するため、単純なifの場合、Elifはメッセージを繰り返し繰り返すだけです(明らかに、ループを閉じていないためです)。私はsys.exit()を見てきましたが、正しく使用しない限り、赤いテキストの巨大なブロックも出力します。同じモジュールに、このようなものを実装する必要のある他のクラスがあるため、ループで例外をキャッチしたくありません。

18
user2560035

_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()を使用できます。

8
The-IT

深度を制限することにより、トレースバックをオフにすることができます。

Python 2.x

import sys
sys.tracebacklimit = 0

Python 3.x

Python 3.5.2 and 3.6.1、setting 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>
51
Marco Costa

税関例外のトレースバックを取り除き、行番号を取得する場合は、このトリックを実行できます

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

私が知っている最もクリーンな方法は、_sys.excepthook_を使用することです。

typevalue、およびtracebackを受け入れる3つの引数の関数を実装し、好きなことを行い(たとえば、値を出力するだけ)、その関数を_sys.excepthook_。

次に例を示します。

_import sys

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

sys.excepthook = excepthook

raise ValueError('hello')
_

これは、python 2とpython 3。

4
Mark Veltzer

一般に、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

複数の例外が発生した場合、1つのメッセージのみが出力されることに注意してください。

この回答は One by The-IT を改善するためのものです。

2
Acumenus