What’s New In Python 3.0 ノート

What’s New In Python 3.0 を読んで、個人的に関心のある項目に注釈を付けていく。

要注意項目

メジャーバージョンアップによる劇的な変更点を記述している。

  • print が関数化した。キーワード引数の仕様を確認したい。

    • sep は引数を区切る文字列。

    • end は引数をすべて出力したあとにさらに追加的に出力する文字列。

    • file は出力先オブジェクト。メソッド write() を実装していることを必要とする。

  • かなりのメソッドや関数が listdict オブジェクトではなく、その iterator を返すように変更された。効率を考えるとそのほうがうれしい。

    本当に listdict オブジェクトが欲しい場合には、戻り値を明示的にそれらのコンストラクターの引数にしてオブジェクトを生成すればよい。

    • dictiter から始まるメソッド群は廃止。名前に iter のつかないメソッドが iterator を返すようになったので要らない。

    • filter も iterator を返すようになったが、個人的には元々これを使わない。内包表記のほうが書きやすいし効率的らしいから。

    • xrange は廃止。range が変更されて、list ではなく、何らかの iterable オブジェクトを返すようになったため。

    • zip は iterator を返す。

  • 比較周りが変更。

    • < などで両辺の型がマッチしないと TypeError が送出されるように変更された。0 < None のような評価もこの例外送出が起こるので、ある意味では C/C++ より厳密だ。

    • sort 系で cmp 引数が廃止された。これは C の qsort のアレだ。代わりに key 引数を用いる。この key 引数はキーワード専用引数なので、利用するのに仮引数名への代入の明示が必要。ちなみに reverse も同様。

    • cmp() が廃止された。つまり __cmp__() も無意味になった。__le__()__eq()__ を使う。

      • そもそも cmp(a, b) とは (a > b) - (a < b) だ。

  • 整数型の変更点はけっこう注意が要る。

    • longint に吸収統合された。

    • int / int の結果は float になる。 C 言語のような振る舞いが望みならば int // int とする。

    • 八進数リテラルのプレフィックスが変更されたが、個人的にはこの基数は使わない。

  • 文字列周り

    • 文字列は str しかない。しかも Unicode 文字列である。

    • u プレフィックスは廃止。

    • strbytes は混在して使えない。両者を変換するメソッドやコンストラクターが提供されている。

    • 自分ではやろうとは思わないが、非 ASCII 文字を識別子に使える。

    • StringIO, cStringIO は廃止。io.StringIO または io.BytesIO を採用すればよい。

構文周り

メジャーバージョンアップということで言語構文の変更がある。

新規の構文仕様

  • 関数の引数と戻り値に対して注釈を付けられるようになった。これも使わない。

  • キーワード専用引数。キーワード引数であることを呼び出し側も明示しないといけない機能。すなわち、必要に応じて仮引数名イコール実引数と書く。

  • 予約語 nonlocal の追加。入れ子の関数を書くときに有用。入れ子の関数スコープから、その外側の関数スコープの変数にアクセスするのに用いる。

  • 左辺で iterator の unpack が可能になった。a, b, *rest = some_sequence

  • dictlist のように内包的記法ができるようになった。実行効率も期待できる。

  • set が外延的記法と内包的記法のどちらでもオブジェクトを定義できるようになった。

    • {2, 4, 6, 8, 10}

    • {x * 2 for x in range(1, 5)}

    • ただし空集合は set() としか書けない。

  • 二進数の指定が楽になった。ROM 解析のビットフラグを見るのに使いたい。リテラル値の指定に 0b プレフィックスが使える。

    • 関数 bin() も整数を二進数で表すのに便利だ。

  • バイトリテラルもある。プレフィックス b が付いた文字列リテラルとして値を宣言する。または bytes() でオブジェクトを生成することができる。

変更された構文仕様

  • 例外送出構文が raise [expr [from expr]] に変更された。

  • as, with が予約語になった。

  • True, False, None が予約語になった。

  • 例外ハンドルのキャッチ部の文法が変更された。except TypeError as e のように書く。

廃止された構文仕様

  • 整数型の統合により L サフィックス廃止。

  • 文字列の Unicode 化により u プレフィックス廃止。

  • from module import * 文はモジュールレベルでしか利用できなくなった。

Python 2.6 での変更

Python 3.0 用の機能仕様が一部 2.6 にも導入されているので、そちらのドキュメントを当たること。

  • with A as B 文。

  • multiprocessing モジュール。

  • 進化版文字列書式、すなわち format() と中括弧をふんだんに使う書式文字列のタッグ。

  • io モジュール。

  • abc モジュール。

  • クラスデコレーター。

  • numbers モジュール。

標準ライブラリーの変更

What’s New では時間的制約のため、変更点を要点にしぼって記述している。

  • 大量の古いモジュールが撤廃された。使っていないものばかりなので見なくていい。

  • いくつかのモジュールの名前が変更された。個人的には configparser だけ注意すれば良さそうだ。

  • urllib 周りのモジュールがここに統廃合された。

  • __builtins__builtins に改名。

文字列フォーマット

文字列の % 演算子ではなく、str.format()format() を使うようになる。

例外に関係する仕様の変更

  • すべての例外クラスは直接的または間接的に BaseException の派生クラスであるものとする。

    • ただし、ユーザーが例外クラスを定義するならば Exception を直接的または間接的に継承するのが当然だ。したがって「すべての例外を捕捉する」を意味するコードは except Exception となる。

    • 例外の送出構文が変更された。

    • 例外の捕捉構文が変更された。

    • すごく難しいのだが raise SecondaryException() from primary_exception 構文。

    • 例外オブジェクトの __traceback__ メンバーにトレースバックがセットされるようになった。

    • Windows が拡張モジュールのロードに失敗したときの例外メッセージがマシになった。これは PyQt や Pillow などの DLL が何かおかしいときに実行時に出るエラーのことか。

その他の変更

演算子、特殊メソッド

  • a != ba == b の評価が常に逆になるようになった。以前は何だった?

  • __slice__() 系は廃止された。

  • iterator.next()iterator.__next__() に名前を変えた。

  • __nonzero()____bool__() に名前を変えた。

組み込み

  • super() が使いやすくなった。引数なしで呼べるのがありがたい。

  • raw_input()input() に改名。

  • 関数 next() で iterator を進めることができる。この関数は上述の iterator.__next__() を呼び出すことになっている。

  • apply()reduce() が廃止。それはそうだ。

  • callable() が廃止。代替案が面倒なので、こういうコードは良くないということだろう。

  • file 型が廃止。open() でさまざまなストリームを生成できる。

  • dict.has_key() が廃止。in 演算子を用いればよい。