Python 2最後のバージョンと公言される2.7のリリースも近づき,いよいよPython 3移行の足音が大きく鳴り響いてくるようになりました。フレームワークや各種サードパーティライブラリの3追従はまだ時間がかかると見込まれるものの,スタンドアロンな,またはPython 3に対応したライブラリのみに依存して書けるたぐいのスクリプトについては,そろそろ3で動かすことを意識してもよい時期に来ていると言えます。
2と3両方で動くプログラムを書くのは実はそれほど難しくありません。いくつか具体的な方法を挙げると
- 辞書型のhas_key()のように3で廃止された機能を使わないようにする
- printのように文から関数になった機能については,myprint()のような非互換製を吸収する俺関数を作って使う
- from __future__ import 〜をできる限り活用する
- 改名,または場所の変わったモジュールについては,try〜exceptで対応
try:
from cStringIO import StringIO # Python 2.xのStringIOをimportしてみる
except:
from io import StringIO # 例外が発生したら,Python 3.xのStringIOをimport
ただ,こういった自助努力的なコードをいちいち書いているのは面倒。もっと手軽にPython 2と3両方で動くスクリプトを書きたい人は,Sixのようなモジュールを使うといいかもしれません。Sixは,Python 2と3の間で互換レイヤーを提供してくれるモジュールです。
たとえば,printについてはsix.syntax.print_という,俺関数に相当する関数が提供されています。スクリプトでこの関数を使えば,printを使う場面でPython 2と3の互換性に悩む必要はない。モジュールの変更については,six.movesというパッケージが提供されています。このパッケージから,2と3で置き場所や名前が異なるモジュールをインポートすれば,Sixがうまいこと間を取り持ってくれるわけです。
Python 3で追加されたbytes型をエミュレート(?)してくれるデータ型なども提供されています。クラスへのデコレーションなど,言語に依存する機能は補完してくれないけど,大抵の場面ではSixを使えばPython 2と3両方で動くプログラムを手軽に書けるようになるはずです:-)。