もっと知りたいPython3000

第3回 言語仕様,組み込み関数,クラスへの変更

この記事を読むのに必要な時間:およそ 3 分

イテレータを返すようになる組み込み関数

前回,辞書型のメソッドkeys(),values()などの変更について書きました。2.xではリストを返していたこれらのメソッドは,3.0ではイテレータ風のviewと呼ばれるオブジェクトを返します。

同様の変更が,リストを返す組み込み関数の返り値に対しても施されます。たとえば,Python 3.0では組み込み関数のrange()はイテレータ風のrangeオブジェクトを返すようになります。それに伴って,xrange()は廃止されます。xrange()はもともと,すべての要素を含む粒度の高いリストオブジェクトを返すrange()の代わりにイテレータ風のオブジェクトを返す関数として用意されたものでした。ループを作るためなどに大きなサイズのシーケンスを生成するときにはxrange()を使っていましたが,range()がイテレータを返すようになって,必要がなくなったわけです。

また,map(),filter(),zip()などもイテレータを返すようになります。range()を含めこのような関数の戻り値がリストであることを期待して,sort()などのメソッドを呼んだり,インデックスやスライスで要素を取り出そうとするとエラーになります。

メタクラスに関する変更

メタクラスという高貴な響きを持つ言葉の全体像を短く説明するのは大変難しいことです。多少乱暴に言うと,クラス生成をフックすることで,インスタンスの生成時にいろいろな処理を行う仕組みをメタクラスと呼びます。ダイナミックな型付け言語としての特長を生かし,クラス設計の抽象性,柔軟性を増すことによって,開発をより効率化することができます。

メタクラスを使うと,状況に合わせてクラスの振る舞いを変更したり,動的に機能を追加できます。データベース上のデータをPythonのオブジェクトとして扱えるようにするO/Rマッパーは,単純な設定をするだけで豊富な機能を持ったクラスを生成できますが,このようなことができるのがメタクラスの利点の1つといえます。

Python 3.0では,メタクラスの仕組みをより強力にサポートし,より一貫性のある仕様にするため,いろいろな変更が計画されています。

メタクラスを作るには,typeを継承したクラスを作り,__new__() という初期化を行うメソッドを定義します。2.xでは,クラスアトリビュート __metaclass__ にtypeを継承したクラスを代入することで,このクラスをインスタンス生成時に呼び出す指定をしていましたリスト7⁠。

リスト7 Python 2.xでのメタクラスの作成

class Klass:
    __metaclass__ = MetaKlass
             :

Python 3.0からは,特別なアトリビュートを使う変わりにクラス定義時にキーワード引数を渡す,というよりきれいな記述方法になっています。クラスを継承する際には,メタクラス指定のキーワード引数の前に親クラス名を指定します。

リスト8 Python 3.0でのメタクラス作成

class Klass(metaclass = MetaKlass):

その他,クラス定義時にKlass(*baseclasses) のようにベースクラスをリストで渡したり, **kws のようにキーワード引数を辞書渡しする記法も可能になっています。ベースクラスやメタクラスに渡すキーワード引数を動的に指定できるようになるわけです。typeを継承するメタクラスには,__prepare__ というクラス本体の評価前に呼ばれる特殊メソッドが追加されました。

関数への注釈(Function Annotations)

Python 3.0では,関数の引数などに注釈を付けるためのFunction Annotationsという記法が導入されます。これまで,関数やメソッドの解説は,def文の直後に置くドキュメンテーション文字列(Doc String)に記述してきました。それと同じように,引数や,関数の戻り値に対して注釈を付けることができるようになります。リスト9のような記法になります。

リスト9 注釈の入れ方

def func(arg1 : "引数の説明1",
         arg2 : "引数の説明2" = 1) -> "返り値の説明":
    # 関数定義

コロンや -> の後に置く文字列は,辞書オブジェクトに格納されます。実際は記述してある表記を式として評価して辞書に格納されます。文字列だけでなく関数呼び出しや,関数オブジェクト(関数名)を置くこともできます。

Function Annotationsの辞書は,関数の持つ__annotations__ という辞書に格納されます。文字列の変わりに引数チェック用の関数オブジェクトを指定し,デコレータと組み合わせることによって,手軽に引数や返り値の型チェックが行えるようになるわけです。

その他の変更

その他の変更点について,手短にまとめてみます。

比較に関する変更
「!=」と同じ意味を持つ「<>」が使えなくなります。
raw_input()の廃止
raw_input()相当の機能がinput()に置き換わります。入力内容をevalするinput()はなくなります。
グローバル関数の廃止
apply(),callable(),coerce(),file(),reduce(),reload()がグローバル関数から削除されます。
クラスデコレータ
関数デコレータと同じ表記で,クラスにデコレータを追加できるようになります。
モジュールの統廃合,改名
PEP 8に沿わない名前を持つモジュールが改名されます。また,cPickleがpickleになるなど,一部モジュールが廃止されます。再配置が行われるモジュールもいくつかあります。

次回は,Python 2.xから3.0への移行方法や,2.xと3.0間で互換性を保つための方法について解説します。

著者プロフィール

柴田淳(しばたあつし)

Webcore株式会社代表取締役。Python,Ploneを使ったCMS/システム構築やコンサルティングが主な業務となっています。「みんなのPython」「TurboGears×Python」などの著書があります。日本Pythonユーザ会のほか,日本PostgreSQLユーザ会でも活動。

URLhttp://coreblog.org/ats/

著書