LoginSignup
27
18

More than 5 years have passed since last update.

エラーの情報を取得するmessageとwith_traceback

Last updated at Posted at 2017-12-14

Python 3.6.3 でエラーの情報を取得する際に.messageが使えなかった。

2015年にQiitaにまとめられた記事でpythonの勉強をしていて、エラーの情報を取得する回に

[example.py]
try:
    a = 10 / 0
    print("{0}".format(a))
except ZeroDivisionError as e:
    print("message:{0}".format(e.message))

と処理する際に

Traceback (most recent call last):
  File "py3.division_by_zero_info.py", line 9, in <module>
    print("message:{0}".format(e.message))
AttributeError: 'ZeroDivisionError' object has no attribute 'message'

とAttributeErrorが出てうまく取得できなかった。

dir()でエラーの持つアトリビュートが調べられる

色々調べまわっていると、dir()でオブジェクトの持つアトリビュートの一覧を確認できることを発見して早速試すと、

[dir.py]
try:
  a = 10 / 0
  print("{0}".format(a))
except Exception as e:
  print(dir(e))

以下、結果

['__cause__', '__class__', '__context__', '__delattr__', '__dict__', '__dir__', 
'__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', 
'__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', 
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', 
'__sizeof__', '__str__', '__subclasshook__', '__suppress_context__', '__traceback__', 
'args', 'with_traceback']

バーっと出てきた。argsは問題なさそう。messageは見当たらない。

気になるのでバージョンを下げて(2.7.14)、もう一度dir()を試す。

['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__',
 '__getitem__', '__getslice__', '__hash__', '__init__', '__new__', '__reduce__', 
'__reduce_ex__', '__repr__', '__setattr__',
'__setstate__', '__sizeof__', '__str__', '__subclasshook__', '__unicode__', 
'args', 'message']

message 発見ーーーー。

messageで出力する

2.7.14のままmessageで出力してみる。

[message.py]
try:
  a = 10 / 0
  print("{0}".format(a))
except Exception as e:
  print("message:{0}".format(e.message))

以下、結果

message:integer division or modulo by zero

ちゃんと取得できた!

with_tracebackで出力する

3.6.3に戻してwith_tracebackで出力する。
with_tracebackを使う場合はsysをimportしてスタックトレース(処理を順番に格納すること?)の情報をexec_info()で取得した上で行う。

[with_traceback.py]
import sys
try:
  a = 10 / 0
  print("{0}".format(a))
except Exception as e:
  tb = sys.exc_info()[2]
  print("message:{0}".format(e.with_traceback(tb)))

以下、結果

message:division by zero

無事に出力できた。
情報の内容も少し異なっているし、基底になっているクラスの違いもあるようで(内容が異なっているのかはわかってない)、そういうのも関係しているんでしょうか・・・

お世話になりました。

Python基礎講座(11 例外) - Qiita
Pythonの組み込み例外の木構造を見てみる - Qiita
オブジェクトのアトリビュートの一覧を取得す
5. 組み込み例外 — Python 3.6.3 ドキュメント
29.1. sys — システムパラメータと関数 — Python 3.6.3 ドキュメント

27
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
18