SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

japan.internet.com翻訳記事

Python 3.0開発者ガイド:コア言語の変更点

Python 3.0の主要な言語機能

PEP-3134:例外チェーンと埋め込みトレースバック

 Python 3.0では、例外オブジェクトに新たに__context____cause____traceback__の3つの属性が追加されました。__context__属性は、もともと別の例外の処理中に発生した例外を明示的に発生させるときに役立ちます。Python 2.xでは、次に示すように元の例外が失われ、2番目の例外に置き換わっていました。

>>> try:
...   raise Exception('first')
... except:
...   raise Exception('second')
...
Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
Exception: second

 Python 3.0で同じコードを実行すると次のようになります。

>>> try:
...   raise Exception('first')
... except:
...   raise Exception('second')
...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
Exception: first

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
Exception: second

 このように、2番目の例外オブジェクトが元の例外オブジェクトを__context__属性に格納します。

>>> e.__context__
Exception('first',)
>>> type(e.__context__)
<class 'Exception'>

 ネストされたtry-exceptブロックがある場合は、この例外チェーンの処理を次々に続けることができます。それぞれの例外が、その前の例外を__context__に格納します。

 __cause__属性は、ある例外を別の例外に明示的に変換するときに役立ちます。構文はraise EXCEPTION from CAUSEです。CAUSEも例外でなければなりません。次に例を示します。

try:
  raise Exception('duh!') from Exception('Gigi')
except Exception as e:
  assert e.__context__ is None
  assert repr(e.__cause__) == "Exception('Gigi',)"

 私には、この構文が必要な理由がよく分かりません。from CAUSEはシンタックスシュガーにすぎません。CAUSE__context__に格納されることを除けば、これは次の構文と同等だからです。

try:
  try:
    raise CAUSE
  except:
    raise EXCEPTION

 一方の形式では元の例外が__context__に格納され、もう一方の形式では__cause__に格納されると、まぎらわしくて複雑なエラー処理コードを生む可能性があります。どうなるのかわからないので、捕捉された例外だけでなく、__cause____context__も確認する必要があります。シンタックスシュガーのfrom CAUSEはともかくとして、CAUSE__context__に格納されるべきだと思います。

 Exceptionのもう1つの新しい属性が__traceback__で、これは例外の原因を知らせるトレースバックオブジェクトです。Python 2.xでは、sys.exc_info()[2]またはsys.exc_tracebackを呼び出してトレースバックオブジェクトを取得する必要がありました。それが例外オブジェクト自体の属性となったため、以前より見つけやすくなり、コードもより簡潔になります。トレースバックオブジェクトの意味を理解できるように、tracebackモジュールを忘れずに使用してください。

import traceback

def f():
  g()

def g():
  raise Exception('nested')

t = None
try:
  f()
except Exception as e:
  t = e.__traceback__
  print('----------------')
  print('The  stack trace')
  print('----------------')
  traceback.print_tb(t)
  print('----------------')

----------------
The  stack trace
----------------
  File "article_1.py", line 244, in <module>
    f()
  File "article_1.py", line 237, in f
    g()
  File "article_1.py", line 240, in g
    raise Exception('nested')
----------------

まとめ

 この『Python 3.0開発者ガイド』シリーズの最初の記事では、コア言語と型システムの重要な変更点について説明しました。シリーズの次の記事では、数値、テキスト、バイナリデータの各基本データ型がPython 3.0でどのように扱われるかに焦点を当てます。

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
japan.internet.com翻訳記事連載記事一覧

もっと読む

この記事の著者

japan.internet.com(ジャパンインターネットコム)

japan.internet.com は、1999年9月にオープンした、日本初のネットビジネス専門ニュースサイト。月間2億以上のページビューを誇る米国 Jupitermedia Corporation (Nasdaq: JUPM) のニュースサイト internet.comEarthWeb.com からの最新記事を日本語に翻訳して掲載するとともに、日本独自のネットビジネス関連記事やレポートを配信。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

Gigi Sayfan(Gigi Sayfan)

 主に大規模分散システムを対象とした、C/C++/C#/Python/Javaによるクロスプラットフォームのオブジェクト指向プログラミングに精通。現在は、Numenta社で脳の働きを模した人工知能システムの開発に取り組んでいる。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/4051 2009/06/25 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー