SHOEISHA iD

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

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

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

japan.internet.com翻訳記事

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

Python 3.0の主要な言語機能

PEP-3109:Python 3000での例外の発生

 Python 2.xでは、次の2つの同等の方法で例外を発生させることができます。

Python 2.xでの例外1
raise E, V
raise E(V)

 どちらの場合も、Eが例外クラスでVが値です。しかし、Python 3.0では2番目の形式のみを使用できます。Python 2.xでは、任意のトレースバックを使って例外を発生させるもう1つの(めったに使われない)方法もサポートされています。

Python 2.xでの例外2
raise E, V, T

 Python 3.0では、これは次のようになります。

Python 3.0での例外
e = E(V)
e.__traceback__ = T
raise E

 Python 3.0の形式の方が煩雑ですが、この形式で例外を発生させることはめったにないので、重要ではありません(例外に任意のトレースバックを付けるような用途が、私には1つも思い浮かびません)。exceptまたはfinallyブロック内でアクティブな例外を再度発生させたい場合は、引数を付けずにraiseを使い続けます。

 ジェネレータには、raise E, V, T形式と同じように、3つの引数を受け取るthrow()メソッドを使って例外を発生させる非同期の機能がありました。Python 3.0では、throw()は1つの例外引数しか受け取らないので、raiseと一貫性が保たれています。

PEP-3110:Python 3000での例外の捕捉

 Python 2.xでは、例外の捕捉の構文とセマンティクスにいくつかの問題があります。例えば、例外型とそのインスタンスを捕捉するには、次のようなセマンティクスを使います。

except <expression_1>, <expression_2>:

 2つの例外型を捕捉する必要がある場合は、次のように型をかっこで囲むことができました。

except (<expression_1>, <expression_2>):

 困ったことに、かっこを付け忘れると、この構文が厄介なバグを引き起こすことがあります。次のコードでは、except句でExceptionstrを(かっこを付けずに)捕捉しています。本来の意図は、汎用Exceptionクラスまたはstr型を捕捉することです。しかし、その意図に反して、実際はException型のみが捕捉されます。Exceptionの特定のインスタンス(この例ではDivisionInZeroException)がstrに代入されます。str()を後から使おうとすると、意味不明で悲惨な結果に終わります。

>>> try:
...   3 / 0
... except Exception, str:
...   print repr(str)
... 
ZeroDivisionError('integer division or modulo by zero',)
>>> str(5)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'exceptions.ZeroDivisionError' object is not callable

 この例外処理コードがたまたまコードのどこか奥深くに埋もれていて、str()がずっと後で使われていたら、見つけ出すのは容易なことではありません。

 Python 3.0では、最初の形式(except TYPE, INSTANCE)を次の形式に置き換えて、これらの問題に対処しています。

except <exception type> as <instance>

 さらに、例外型はexceptions.BaseExceptionから派生していなければなりません。複数の例外型を捕捉する場合は、今までどおりタプル構文を使うことができます。Python 3.0で例外を捕捉する方法の例を次に示します。

>>> try:
...   3 / 0
... except Exception as e:
...   print(repr(e))
... 
ZeroDivisionError('int division or modulo by zero',)

>>> try:
...   3 / 0
... except (Exception, ZeroDivisionError):
...   pass
... 

 例外の捕捉に関連するもう1つの変更点は、sys.exc_typesys.exc_value、およびsys.exc_tracebackが削除されたことです。情報は、次のようにsys.exc_info()から返されるタプルとして得られます。

>>> try: 
...   3/0
... except:
...   print(sys.exc_info())     
... 
(<class 'ZeroDivisionError'>, ZeroDivisionError('int division or modulo by zero',), 
   <traceback object at 0x3bcbc0>)

 将来はsys.exc_info()も削除される可能性があります。exception属性などの代替手段も検討されましたが、既存のコードの自動修正が難しいという理由で見送られました。次のセクションで説明するように、tracebackは属性になりました。

 さらに、Python 3.0ではガベージコレクションの問題を回避するために、except句の最後で例外インスタンスの削除を確認します。

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

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

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」など、さまざまなカンファレンスを企画・運営しています。

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

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

メールバックナンバー