このサイトについて

後方互換性を保ちながら一貫性を得る

後方互換性を保ちながら一貫性を得る

Pythonの組み込み関数にint()というものがあります。このint(),ドキュメンテーションでは組み込み関数として分類されていますが,果たしてそう呼んでいいのかどうか微妙な位置にあります。int()の機能はずっと変わらず,引数として与えられた文字列やfloat型のオブジェクトをint型に変換する,というものなのだけど,バージョンを負うごとに実装が変わっているから。

たとえばPython 1.5では,int()は紛れもなく組み込み関数として実装されています。Python 2.1まで同様。

Python 1.5.2 (#1, Sep 27 2002, 03:18:08)  [GCC 2.95.3 20010315 (release)] on linux-i386
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> int
<built-in function int>

int()が組み込み関数として実装されていて困ることの一つは,継承ができないこと。int()を拡張したクラスを作ろうと思うと,エラーが出ます。ただの組み込み関数なので,継承できないわけです。intやdictなど,組み込み型を継承したいときのために,UserIntやUserDictといった特別なクラスが用意されていて,使われていました。

 Python 2.1.3 (#1, Nov 19 2003, 01:11:20)
[GCC 2.95.3 20010315 (release)] on linux2
Type "copyright", "credits" or "license" for more information.
>>> class foo(int):
...     pass
...
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: base is not a class object

Python 2.2で実装が変更されます。新スタイルクラスが導入されたからです。typeという型が導入され,intはtype型のオブジェクトになりました。

Python 2.2.3 (#1, Nov 19 2003, 01:02:45)
[GCC 2.95.3 20010315 (release)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> int
<type 'int'>

 intオブジェクトには__call__()メソッドが実装されているので,これまでと同様関数のように呼び出しを行うことができますし,intを継承してサブクラスを作ることもできます。intとPythonのファーストクラスオブジェクトobjectの間には継承関係があります。

Python 3.0ではint()の実装が変わりました。

Python 3.0 (r30:67503, Dec  5 2008, 09:49:50)
[GCC 4.0.1 (Apple Inc. build 5484)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> int
<class 'int'>

見れば分かるとおり,intはclassになりました。ユーザがclass文で定義するクラスと同じ立場になったわけです。Pythonでインスタンスを作るときには「klass()」のようにしますので,クラスになっても「int()」のように呼び出しを実行できます。実装は変わりましたが,使い方には変更がありません。後方互換性を保っているわけです。

もともと,「組み込み関数」「組み込み型」「継承専用のクラス」という3つの仕組みを持っていたのが,2.2で型システムという仕組みの元に3つの仕組みが統合され,3.0ではついにユーザ定義のクラスとも統合されました。Pure Pythonレベルではほぼ後方互換性を保ちながら,段階的に実装を変更してきているわけですね。とてもスマートだし,開発者のことをよく考えた仕様変更だと思います。これがPythonの方法論なんですね〜。

ただ,3.0では組み込み型の実装が変わっているので,Cなどで書かれた既存の拡張モジュールではちょっとした移行が必要みたいです。文字列を扱うモジュールは,ユニコードベースに移行しなければならないので,ちょっと大変かも知れません。

2010-08-27 04:49