Pythonの標準ライブラリのコンポーネントから例外のメッセージを取得する最良の方法は何ですか?
場合によっては、次のようにmessage
フィールドから取得できることに気付きました。
try:
pass
except Exception as ex:
print(ex.message)
ただし、場合によっては(たとえば、ソケットエラーの場合)、次のようにする必要があります。
try:
pass
except socket.error as ex:
print(ex)
これらの状況のほとんどをカバーする標準的な方法はあるのだろうか?
組み込みエラーのドキュメント を見ると、ほとんどのException
クラスが最初の引数をmessage
属性として割り当てていることがわかります。しかし、すべてがそうするわけではありません。
特に、EnvironmentError
(サブクラスIOError
およびOSError
)には、errno
の2番目の引数、strerror
の2番目の引数があります。 message
はありません... strerror
は、通常message
になるものとほぼ同じです。
より一般的には、Exception
のサブクラスは何でもできます。 message
属性を持つ場合と持たない場合があります。将来の組み込みException
sにはmessage
属性が含まれない可能性があります。サードパーティのライブラリまたはユーザーコードからインポートされたException
サブクラスには、message
属性がない場合があります。
これを処理する適切な方法は、キャッチする特定のException
サブクラスを特定し、except Exception
ですべての代わりにサブクラスのみをキャッチし、特定のサブクラスが定義する属性を利用することだと思います欲しいです。
print
何かをしなければならない場合、Exception
属性を持っているかどうかに関係なく、キャッチされたmessage
自体を印刷することが、おそらくあなたが望むことをする可能性が高いと思います。
次のように、必要に応じてメッセージ属性を確認することもできますが、面倒だと思われるため、実際には提案しません。
try:
pass
except Exception as e:
# Just print(e) is cleaner and more likely what you want,
# but if you insist on printing message specifically whenever possible...
if hasattr(e, 'message'):
print(e.message)
else:
print(e)
@ artofwarfare によって提供される答えを改善するために、ここにmessage
属性をチェックしてそれを印刷するか、フォールバックとしてException
オブジェクトを印刷するより適切な方法を検討します。
try:
pass
except Exception as e:
print getattr(e, 'message', repr(e))
repr
への呼び出しはオプションですが、使用例によっては必要な場合があります。
#1:を更新:
@ MadPhysicist によるコメントに続いて、ここにrepr
の呼び出しが必要な理由の証拠があります。インタープリターで次のコードを実行してみてください。
try:
raise Exception
except Exception as e:
print(getattr(e, 'message', repr(e)))
print(getattr(e, 'message', str(e)))
更新#2:
Python 2.7および3.5の詳細を含むデモを次に示します。 https://Gist.github.com/takwas/3b7a6edddef783f2abddffda1439f5
同じ問題がありました。最善の解決策はlog.exceptionを使用することだと思います。これにより、次のようなスタックトレースとエラーメッセージが自動的に出力されます。
try:
pass
log.info('Success')
except:
log.exception('Failed')