例外を適切に無視する方法


777

例外を処理せずにtry-exceptを実行したいだけの場合、Pythonではどのように実行しますか?

以下はそれを行う正しい方法ですか?

try:
    shutil.rmtree(path)
except:
    pass

10
今まで誰もそれを言及しなかったのは奇妙です(私は私の答えでしました)が、この特定の機能については、あなたはただ行うことができますshutil.rmtree(path, ignore_errors=True)。ただし、これはほとんどの関数には適用されません。
アーロンホール

9
例外を無視することを考えるときに重要な注意事項:なぜ「except:pass」が不適切なプログラミング手法であるのですか?
2017

3
これを実際の生活で想像してみてください。試してみてください:get_cash( '$ 1000')例外:パス
#meh、それで

実生活:try: rob() except: run()
PatrickT

回答:


1039
try:
    doSomething()
except: 
    pass

または

try:
    doSomething()
except Exception: 
    pass

違いは、最初のものもキャッチしKeyboardInterruptSystemExitそのようなものは、から直接派生するのでexceptions.BaseExceptionはなく、から派生するということexceptions.Exceptionです。

詳細はドキュメントを参照してください:


4
StopIterationとWarningはどちらもExceptionから継承することに注意してください。必要に応じて、代わりにStandardErrorから継承することもできます。
Ben Blank

1
これは事実ですが、注意しないと、微妙なバグに遭遇する可能性があります(特に、StopIterationを渡す以外のことをしている場合)。
Jason Baker、

17
-1、try: shuti.rmtree(...) except: pass粗(あなたはスペルを間違えても、すべてのエラーを抑制しますshutilその結果NameError) -最低で行うexcept OSError:
DBR

44
この回答は有益ではありますが、重要な情報が欠落しています-この方法で例外をキャッチすることはできません。代わりに、気になる例外だけを常にキャッチしようとする必要があります。そうしないと、一般的な "except"によって隠された些細なバグを探すときに悪夢になります。詳細については、dbrの回答を参照してください。(私はこれが元の質問ではなかったことを知っています-しかし、これを探している人はあなたのスニペットをそのまま使用します)
johndodo

139

一般的に、関心のあるエラーのみをキャッチすることがベストプラクティスであると考えられています。shutil.rmtreeおそらくOSError次のような場合です。

>>> shutil.rmtree("/fake/dir")
Traceback (most recent call last):
    [...]
OSError: [Errno 2] No such file or directory: '/fake/dir'

そのエラーを黙って無視したい場合は、次のようにします。

try:
    shutil.rmtree(path)
except OSError:
    pass

どうして?次のように、誤って関数に文字列ではなく整数を渡したとします。

shutil.rmtree(2)

「TypeError:coercing to Unicode:need string or buffer、int found」というエラーが表示されます-おそらく無視したくないので、デバッグするのは難しいかもしれません。

間違いなくすべてのエラーを無視したい場合Exceptionは、裸のexcept:ステートメントではなくキャッチしてください。もう一度、なぜですか?

例外を指定しないと、たとえば次のものを使用する例外を含め、すべての例外がキャッチさます。SystemExitsys.exit()

>>> try:
...     sys.exit(1)
... except:
...     pass
... 
>>>

これを、正しく終了する以下と比較してください。

>>> try:
...     sys.exit(1)
... except Exception:
...     pass
... 
shell:~$ 

より優れた動作のコードを記述したい場合、OSError例外はさまざまなエラーを表す可能性がありますが、上記の例では無視するだけなErrno 2ので、より具体的にすることができます。

import errno

try:
    shutil.rmtree(path)
except OSError as e:
    if e.errno != errno.ENOENT:
        # ignore "No such file or directory", but re-raise other errors
        raise

1
shutil.rmtreeあなただけ使用するので、最良の例ではありませんignore_errors=True、その関数のために...
WIM

113

例外を処理せずにtry catchを実行したいだけの場合、Pythonではどのように実行しますか?

それは、「処理」の意味によって異なります。

何もせずにキャッチするつもりなら、投稿したコードは機能します。

例外がスタックから上がるのを止めずに、例外に対してアクションを実行したい場合は、次のようにします。

try:
    do_something()
except:
    handle_exception()
    raise  #re-raise the exact same exception that was thrown

88

まず、このスレッドからジャック・オコナーの答えを引用します。参照されたスレッドが閉じたので、ここに書きます:

「Python 3.4でこれを行う新しい方法があります。

from contextlib import suppress

with suppress(Exception):
    # your code

これを追加したコミットは次のとおりです。http//hg.python.org/cpython/rev/406b47c64480

そして、これが作者のレイモンドヘッティンガーで、これと他のあらゆる種類のPythonの熱さについて語っていますhttps : //youtu.be/OSGv2VnC0go? t =43m23s

これに私が追加したものは、Python 2.7に相当するものです。

from contextlib import contextmanager

@contextmanager
def ignored(*exceptions):
    try:
        yield
    except exceptions:
        pass

次に、Python 3.4のように使用します。

with ignored(Exception):
    # your code

55

完全を期すために:

>>> def divide(x, y):
...     try:
...         result = x / y
...     except ZeroDivisionError:
...         print("division by zero!")
...     else:
...         print("result is", result)
...     finally:
...         print("executing finally clause")

また、次のように例外をキャプチャできることにも注意してください。

>>> try:
...     this_fails()
... except ZeroDivisionError as err:
...     print("Handling run-time error:", err)

...そして次のように例外を再発生させます:

>>> try:
...     raise NameError('HiThere')
... except NameError:
...     print('An exception flew by!')
...     raise

... Pythonチュートリアルの例。


43

例外を適切に無視する方法は?

これにはいくつかの方法があります。

ただし、例の選択には、一般的なケースをカバーしない単純なソリューションがあります。

例に固有:

の代わりに

try:
    shutil.rmtree(path)
except:
    pass

これを行う:

shutil.rmtree(path, ignore_errors=True)

これはに固有の引数shutil.rmtreeです。次のようにするとヘルプが表示され、エラー時の機能も使用できることがわかります。

>>> import shutil
>>> help(shutil.rmtree)

これは例の狭いケースしかカバーしていないため、これらのキーワード引数が存在しなかった場合の対処方法をさらに示します。

一般的方法

上記は例の狭いケースしかカバーしていないので、これらのキーワード引数が存在しない場合にこれを処理する方法をさらに示します。

Python 3.4の新機能:

suppressコンテキストマネージャをインポートできます。

from contextlib import suppress

ただし、最も具体的な例外のみを抑制します。

with suppress(FileNotFoundError):
    shutil.rmtree(path)

あなたは黙って無視しFileNotFoundErrorます:

>>> with suppress(FileNotFoundError):
...     shutil.rmtree('bajkjbkdlsjfljsf')
... 
>>> 

ドキュメントから:

例外を完全に抑制する他のメカニズムと同様に、このコンテキストマネージャは、プログラムの実行を静かに続行することが正しいことであることがわかっている非常に特定のエラーをカバーする場合にのみ使用してください。

suppressFileNotFoundErrorはPython 3でのみ使用できることに注意してください。

コードをPython 2でも機能させる場合は、次のセクションをご覧ください。

Python 2&3:

例外を処理せずに単にtry / exceptを実行したい場合、Pythonではどのように実行しますか?

以下はそれを行う正しい方法ですか?

try :
    shutil.rmtree ( path )
except :
    pass

Python 2互換コードpassの場合、何もしないステートメントを作成する正しい方法です。あなたが裸を行うときにはexcept:、それはやって同じだexcept BaseException:含まれているGeneratorExitKeyboardInterruptSystemExit、一般的に、あなたはそれらのものをキャッチする必要はありません。

実際、例外の命名はできるだけ具体的にする必要があります。

これはPython(2)例外階層の一部であり、ご覧のとおり、より一般的な例外をキャッチすると、予期しない問題を隠すことができます。

BaseException
 +-- SystemExit
 +-- KeyboardInterrupt
 +-- GeneratorExit
 +-- Exception
      +-- StopIteration
      +-- StandardError
      |    +-- BufferError
      |    +-- ArithmeticError
      |    |    +-- FloatingPointError
      |    |    +-- OverflowError
      |    |    +-- ZeroDivisionError
      |    +-- AssertionError
      |    +-- AttributeError
      |    +-- EnvironmentError
      |    |    +-- IOError
      |    |    +-- OSError
      |    |         +-- WindowsError (Windows)
      |    |         +-- VMSError (VMS)
      |    +-- EOFError
... and so on

おそらくここでOSErrorをキャッチしたいと思うでしょう。おそらく気にしない例外は、ディレクトリがない場合です。

ライブラリから特定のエラー番号を取得errno、それがない場合は修正します。

import errno

try:
    shutil.rmtree(path)
except OSError as error:
    if error.errno == errno.ENOENT: # no such file or directory
        pass
    else: # we had an OSError we didn't expect, so reraise it
        raise 

注意:ベアレイズでは元の例外が発生しますが、これはおそらくこの場合に必要なものです。pass例外処理でコードを明示的に指定する必要がないため、より簡潔に記述されています。

try:
    shutil.rmtree(path)
except OSError as error:
    if error.errno != errno.ENOENT: # no such file or directory
        raise 

11

例外を処理せずにtry catchを実行したいだけの場合、Pythonではどのように実行しますか?

これは、例外が何であるかを印刷するのに役立ちます:(つまり、例外を処理せずにキャッチして、例外を印刷してください。)

import sys
try:
    doSomething()
except:
    print "Unexpected error:", sys.exc_info()[0]

10
try:
      doSomething()
except Exception: 
    pass
else:
      stuffDoneIf()
      TryClauseSucceeds()

ちなみに、else句はすべての例外の後に進むことができ、tryのコードが例外を引き起こさない場合にのみ実行されます。


1
最後にelse、このコンテキストでの適切な説明。そして、それを追加するfinallyと、常に実行されます(または例外なし)。
not2qubit 2018年

5

私は複数のコマンドのエラーを無視する必要があり、fuckitはトリックをしました

import fuckit

@fuckit
def helper():
    print('before')
    1/0
    print('after1')
    1/0
    print('after2')

helper()

+1あなたは間違いなく私の日を作ったので、このソースコード内でライブスタックの変更などの非常に便利なことを学ぶことができます
WBAR

3

Pythonでは、他の言語と同様に例外を処理しますが、違いは構文の違いです。たとえば、

try:
    #Your code in which exception can occur
except <here we can put in a particular exception name>:
    # We can call that exception here also, like ZeroDivisionError()
    # now your code
# We can put in a finally block also
finally:
    # Your code...

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.