635

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

次のようにしますか?

try:
    shutil.rmtree(path)
except:
    pass


  • 今まで誰もそれを述べていなかったのは奇妙なことです(私の答えではしませんでした)が、この特定の機能のために、あなたはただすることができますshutil.rmtree(path, ignore_errors=True)。ただし、これはほとんどの機能には適用されません。 - Aaron Hall
  • 例外を無視することを考えるときの重要な読み:なぜ「except:pass」は不適切なプログラミング方法なのでしょうか。 - poke
  • 実生活でこれを行うことを想像してください。試してください。get_cash(' $ 1000')を除いて:pass#meh、おそらく大丈夫でしょう - Grokodile

12 답변


886

try:
  doSomething()
except: 
  pass

または

try:
  doSomething()
except Exception: 
  pass

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

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


  • StopIterationとWarningはどちらもExceptionからも継承されます。あなたのニーズによっては、代わりにStandardErrorから継承したいかもしれません。 - Ben Blank
  • @ベン:これらは両方とも「通常」です。例外がありますので、問題ありません。 - vartec
  • これは事実ですが、注意しないと微妙なバグに遭遇する可能性があります(特にStopIterationを渡さない以外のことをしている場合)。 - Jason Baker
  • -1、try: shuti.rmtree(...) except: pass(あなたがスペルミスをしていても)粗雑にエラーを抑制しますshutilになりますNameError) - 少なくともするexcept OSError: - dbr
  • この回答には有益な情報がありますが、重要な情報が欠けています - このように例外をキャッチすることは絶対に避けてください。代わりに、常に気になる例外だけをキャッチするようにしてください。そうしないと、一般的な「except」に隠された、ささいなバグを探すときに悪夢が出ることになります。詳細については、dbrの回答をご覧ください。 (私はこれが最初の質問ではなかったことを知っています - しかしこれを探している人はただあなたのスニペットを取ってそのまま使うでしょう) - johndodo

121

一般的には、あなたが興味を持っているエラーだけを捉えることがベストプラクティスと考えられています。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:Unicodeへの強制:文字列またはバッファが必要、intが見つかりました" - あなたはおそらくそれを無視したくないでしょう。デバッグは難しいかもしれません。

もし、あんたが絶対にすべてのエラーを無視したい、キャッチException裸ではなくexcept:ステートメント。繰り返しますが、なぜでしょうか。

例外キャッチを指定しないすべてのを含む例外SystemExitたとえば例外sys.exit()使用します:

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

これを次のものと比較してください。これは正しく終了します。

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

もっとよく振る舞うコードを書きたいなら、OSErrorexceptionはさまざまなエラーを表すことがありますが、上記の例では無視したいだけです。Errno 2そのため、もっと具体的にすることができます。

try:
    shutil.rmtree(path)
except OSError, e:
    if e.errno == 2:
        # suppress "No such file or directory" error
        pass
    else:
        # reraise the exception, as it's an unexpected error
        raise

あなたもimport errnoそしてifif e.errno == errno.ENOENT:


108

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

それはあなたが「取扱い」によって何を意味するかによります。

何もしないでそれをキャッチしようとしている場合は、投稿したコードが機能します。

例外がスタックに上がるのを止めずに例外に対してアクションを取りたいという場合は、次のようなものが必要です。

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


70

最初に、Jack o'Connorの回答を引用します。このスレッド。参照されたスレッドは閉じられたので、ここに書きます。

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

from contextlib import suppress

with suppress(Exception):
    # your code

これを追加したコミットがあります。http://hg.python.org/cpython/rev/406b47c64480

そして、これと作者Raymond Hettingerが、これと他のあらゆる種類の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


54

完全を期すために:

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

...からPythonチュートリアル

また、このような例外を捕捉できることにも注意してください。

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


40

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

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

しかしながら、例の選択は一般的な場合をカバーしない簡単な解決策を持っています。

例に固有のもの:

の代わりに

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)

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

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

からdocs

例外を完全に抑制する他のメカニズムと同様に、   このコンテキストマネージャは、非常に具体的なエラーをカバーするためだけに使用されるべきです。   静かにプログラムの実行を続けることが   正しいことです。

ご了承くださいsuppressそしてFileNotFoundErrorPython 3でのみ利用可能です。

コードをPython 2でも機能させたい場合は、次のセクションを参照してください。

Python 2& A 3:

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

次のようにしますか?

try :
    shutil.rmtree ( path )
except :
    pass

Python 2互換コードの場合pass何もしないというステートメントを持つ正しい方法です。しかし、あなたが裸でやるときexcept:と同じですexcept BaseException:含まれますGeneratorExitKeyboardInterrupt、そしてSystemExitそして、一般的に、あなたはそれらのことを捕らえたくありません。

実際、あなたは可能な限り例外を命名する際に特定のものであるべきです。

これがPythonの一部です(2)例外階層そしてあなたが見ることができるように、あなたがより一般的なExceptionsをキャッチするならば、あなたはあなたが予想しなかった問題を隠すことができます:

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 


12

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

これは、例外が何であるかを表示するのに役立ちます。

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

...

reg、 チロクちゃん


9

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

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


  • 最後にの良い説明elseこの文脈では。そしてそれを追加するfinally意志常にいずれかの後に(または例外なしで)実行します。 - not2qubit

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


0

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

import fuckit

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

helper()


-1

単に上げるこれと同じ例外です。

try:
     raise NameError('Joan')
 except NameError:
     print 'An exception just raised again by Joan!'
     raise

それと同じくらい簡単です。 :)

詳細については、このドキュメントを読んでください。 https://docs.python.org/3.6/tutorial/errors.html


  • なぜしないのかJohnの代わりにraise NameError('Joan')(の場合のみJohn定義されていません) - U9-Forward

-1

Pythonで例外を処理する:例外を発生させる可能性のある疑わしいコードがある場合は、その疑わしいコードをtry:ブロックに入れることでプログラムを防御できます。

try:
    # Your statements .............
except ExceptionI:
    # Your statements.............
except ExceptionII:
    # Your statements..............
else:
   # Your statements

リンクされた質問


関連する質問

最近の質問