pytho****@googl*****
pytho****@googl*****
2011年 12月 11日 (日) 03:06:21 JST
2 new revisions: Revision: 4a1edbcdce8b Author: Naoki INADA <inada****@klab*****> Date: Sat Dec 10 10:01:18 2011 Log: Update 2.7.2: howto/doanddont http://code.google.com/p/python-doc-ja/source/detail?r=4a1edbcdce8b Revision: a43ce26175dd Author: Naoki INADA <inada****@klab*****> Date: Sat Dec 10 10:01:48 2011 Log: merge http://code.google.com/p/python-doc-ja/source/detail?r=a43ce26175dd ============================================================================== Revision: 4a1edbcdce8b Author: Naoki INADA <inada****@klab*****> Date: Sat Dec 10 10:01:18 2011 Log: Update 2.7.2: howto/doanddont http://code.google.com/p/python-doc-ja/source/detail?r=4a1edbcdce8b Modified: /howto/doanddont.rst ======================================= --- /howto/doanddont.rst Sat Nov 27 10:59:11 2010 +++ /howto/doanddont.rst Sat Dec 10 10:01:18 2011 @@ -154,11 +154,11 @@ ------- Python には ``except:`` 節があり、これはあらゆる例外を捕捉します。 -Python のエラーは *すべて* 例外を出しますから、こんなことをすれば +Python のエラーは *すべて* 例外を出しますから、 ``except:`` を使うと 各種のプログラミングエラーがランタイムの問題のように見えてしまい、 -デバグの邪魔になります。 - -以下のコードが好例です:: +デバッグの邪魔になります。 + +以下のコードは、 ``except:`` をなぜ避けるべきなのかを示す良い例です:: try: foo = opne("file") # "open" を打ち間違えた @@ -166,19 +166,33 @@ sys.exit("could not open file!") この 2 行目は :exc:`NameError` を引き起こし、続く except 節で捕捉されます。 -プログラムがエラー終了しますが、実際の問題は ``"file"`` の読み出しと -関係ないことなど、これではまったくわかりません。 - -前述の例はこう書けばマシになります:: +プログラムがエラー終了しますが、実際のエラーが ``"file"`` とは何の関係もな いのに、 +にプログラムが表示するエラーメッセージは ``"file"`` の読み込みにあったよう に +誤解させます。 + +前述の例はこう書くべきでした:: try: - foo = opne("file") # 実行すればすぐ "open" に直すことになる + foo = opne("file") except IOError: sys.exit("could not open file") -``except:`` 節が役立つ状況もあります: たとえば、フレームワークで -コールバックを実行するとき、コールバックがフレームワーク自体の -邪魔をしないようにするのは良いことです。 +このプログラムを実行した場合は、 Python は :exc:`NameError` のトレースバッ クを表示し、 +修正すべき問題を即座に明らかにしてくれます。 + +.. index:: bare except, except; bare + +``except:`` は *全て* の例外を補足します。これには :exc:`SystemExit`, +:exc:`KeyboardInterrupt`, :exc:`GeneratorExit` (これはエラーではなく、 +通常はユーザーコードでキャッチするべきではない例外です) も含まれるので、 +ほとんど全ての場合に ``except:`` を利用してはいけません。 +"通常の" すべてのエラーをキャッチする必要がある場合、たとえばコールバックを +実行するようなフレームワークの場合は、全ての通常の例外の基底クラスである +:exc:`Exception` をキャッチすることができます。 +不幸なことに、 Python 2.x ではサードパーティのコードが :exc:`Exception` +を継承していない例外を発生させる可能性があるので、 ``except:`` を使って +キャッチしたくない例外を手動で再度 raise する必要がある場合があるかも +しれません。 例外 @@ -202,21 +216,22 @@ という場合にも起こります。これをテストする際、ふつうのマシンで、存在するフ ァイル と存在しないファイルに対してだけやったのではバグがないように見えてしまい、 テスト 結果が大丈夫そうなのでコードはそのまま出荷されてしまうことになります。こう して、 -対処されない :exc:`IOError` はユーザの所まで逃げのびて、 -汚いトレースバックを見せることになるのです。 +対処されない :exc:`IOError` (またはその他の :exc:`EnvironmentError`)は +ユーザの所まで逃げのびて、汚いトレースバックを見せることになるのです。 もっと良い方法はこちら:: def get_status(file): try: return open(file).readline() - except (IOError, OSError): - print "file not found" + except EnvironmentError as err: + print "Unable to open file: {}".format(err) sys.exit(1) このバージョンでは、ファイルが開かれて一行目も読まれる (だから、あてになら ない -NFS や SMB 接続でも動く) か、あるいはメッセージが表示されてアプリケーション が -強制終了するかの \*いずれか\* 一方しか起こりません。 +NFS や SMB 接続でも動く) か、あるいはファイルを開くのに失敗した理由について の +全ての情報を含むエラーメッセージを表示してアプリケーションを強制終了するか の +*いずれか* 一方しか起こりません。 とはいえ、このバージョンの :func:`get_status` でさえ、前提としている条件が 多過ぎます --- すぐ終わるスクリプトでだけ使って、長く動作させる、いわゆる @@ -279,20 +294,19 @@ 加えて、なぜか気付かれていない多くのビルトイン関数があります: たとえば :func:`min` と :func:`max` を使えば、大小比較のできるシーケンスな ら 何からでも最小値/最大値を見つけることができるのに、多くの人々が自家製の -:func:`max`/:func:`min` を書いています。また別の超便利な関数は -:func:`reduce` です。古典的な使い方はこういった感じです:: - - import sys, operator - nums = map(float, sys.argv[1:]) - print reduce(operator.add, nums)/len(nums) - -このキュートな小っちゃいスクリプトが、コマンドラインで与えられた数値 -すべての平均値を表示するのです。 :func:`reduce` がすべての数を -合計する部分で、残りは単なる準備や後処理に過ぎません。 - -ついでにメモ。 :func:`float` と :func:`int` と :func:`long` はすべて -文字列型の引数を受け付けますから、パース処理にピッタリです --- ただし -:exc:`ValueError` に対応できるよう準備は必要ですが。 +:func:`max`/:func:`min` を書いています。また別の超便利な関数として、 +シーケンスに対して2項演算を繰り返し適用して最終的に1つの値にまとめる +:func:`reduce` です。 +例えば、階乗を乗算の繰り返しで計算します:: + + >>> n = 4 + >>> import operator + >>> reduce(operator.mul, range(1, n+1)) + 24 + +数値の字句解析をするときには、 :func:`float`, :func:`int`, :func:`long` +は全て文字列の引数を受け取って、不正なフォーマットの文字列の場合には +:exc:`ValueError` を発生させることを覚えておくと便利です。 バックスラッシュで文を続ける ============================================================================== Revision: a43ce26175dd Author: Naoki INADA <inada****@klab*****> Date: Sat Dec 10 10:01:48 2011 Log: merge http://code.google.com/p/python-doc-ja/source/detail?r=a43ce26175dd