例外を処理せずにtry-exceptを実行したいだけの場合は、Pythonでどのようにしますか。
次のようにするのが正しい方法ですか?
try:
shutil.rmtree(path)
except:
pass
try:
doSomething()
except:
pass
または
try:
doSomething()
except Exception:
pass
違いは、最初のものはKeyboardInterrupt
、SystemExit
、およびそのようなものをキャッチすることです。これらはexceptions.BaseException
からではなく、直接exceptions.Exception
から派生しています。
詳細はドキュメントを参照してください。
一般的には、あなたが興味を持っているエラーのみを捉えることがベストプラクティスと考えられています。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が見つかりました" - おそらく無視したくないでしょうが、これはデバッグが困難な場合があります。
間違いなく を使用してすべてのエラーを無視したい場合は、そのままのexcept:
ステートメントではなくException
をキャッチしてください。繰り返しますが、なぜでしょうか。
例外を指定しないと、 every exceptionがキャッチされます。例えば、sys.exit()
で使用されるSystemExit
例外が含まれます。
>>> try:
... sys.exit(1)
... except:
... pass
...
>>>
これを次のものと比較してください。これは正しく終了します。
>>> try:
... sys.exit(1)
... except Exception:
... pass
...
Shell:~$
もっと良く振る舞うコードを書きたいのであれば、 OSError
例外はさまざまなエラーを表すことができますが、上の例では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
とif
をif e.errno == errno.ENOENT:
に変更することもできます。
例外を処理せずにtry catchを実行したいだけの場合は、Pythonでどのようにしますか。
それはあなたが「取扱い」によって何を意味するかによります。
何もしないでそれをキャッチしようとしている場合は、投稿したコードが機能します。
例外がスタックに上がるのを止めずに例外に対してアクションを取りたいという場合は、次のようなものが必要です。
try:
do_something()
except:
handle_exception()
raise #re-raise the exact same exception that was thrown
最初に私はジャックオコナーの答えを このスレッド から引用します。参照されたスレッドは閉じられたので、ここに書きます。
「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
完全を期すために:
>>> 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
例外を正しく無視する方法
これを行うにはいくつかの方法があります。
しかし、例の選択は一般的なケースをカバーしない単純な解決策を持っています。
の代わりに
try:
shutil.rmtree(path)
except:
pass
これを行う:
shutil.rmtree(path, ignore_errors=True)
これはshutil.rmtree
に固有の引数です。次のようにしてヘルプを見ることができます。また、エラーに関する機能性も考慮に入れることができます。
>>> import shutil
>>> help(shutil.rmtree)
これは例の狭いケースだけをカバーしているので、これらのキーワード引数が存在しない場合にこれをどのように処理するかをさらに説明します。
上記では例の狭いケースしか扱っていないので、これらのキーワード引数が存在しない場合の対処方法をさらに説明します。
suppress
コンテキストマネージャをインポートすることができます。
from contextlib import suppress
しかし、最も具体的な例外だけを抑制してください。
with suppress(FileNotFoundError):
shutil.rmtree(path)
FileNotFoundError
を黙って無視します。
>>> with suppress(FileNotFoundError):
... shutil.rmtree('bajkjbkdlsjfljsf')
...
>>>
docs から:
例外を完全に抑制する他のメカニズムと同様に、このコンテキストマネージャはプログラムの実行を黙って続けることが正しいことであると知られている非常に特定のエラーをカバーするためだけに使用されるべきです。
suppress
とFileNotFoundError
はPython 3でのみ利用可能です。
コードをPython 2でも機能させたい場合は、次のセクションを参照してください。
例外を処理せずにtry/exceptを実行したいだけの場合は、Pythonでどのようにしますか。
次のようにするのが正しい方法ですか?
try : shutil.rmtree ( path ) except : pass
Python 2互換のコードでは、pass
が何もしないステートメントを持つ正しい方法です。しかし裸のexcept:
をするとき、それはGeneratorExit
、KeyboardInterrupt
、およびSystemExit
を含むexcept BaseException:
をすることと同じです、そして、一般的に、あなたはそれらの事を捕らえたくありません。
実際、あなたは可能な限り例外を命名する際に特定のものであるべきです。
これはPython(2) exception hierarchy の一部です、そしてあなたが見ることができるように、あなたがより一般的な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
ライブラリから that 特定のエラー番号を取得することができ、それがない場合は再利用できます。
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
例外を処理せずにtry catchを実行したいだけの場合は、Pythonでどのようにしますか。
これは、例外が何であるかを表示するのに役立ちます。
import sys
try:
doSomething()
except:
print "Unexpected error:", sys.exc_info()[0]
try:
doSomething()
except Exception:
pass
else:
stuffDoneIf()
TryClauseSucceeds()
参考までにelse節はすべての例外の後に置くことができ、tryのコードが例外を引き起こさない場合にのみ実行されます。
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...
私は複数のコマンドのエラーを無視する必要があり、 fuckit トリックをしました
import fuckit
@fuckit
def helper():
print('before')
1/0
print('after1')
1/0
print('after2')
helper()