Python 2.6との後方互換性を保つための4種のTips または, 2.7の新機能紹介

Pythonは2.7が2010年7月にリリースされ, 現在では2.8をリリースするかが問題になっているようですが, 今でも旧バージョンである2.6への需要は存在するようです.

ここでは, 2.6互換にするために注意する点を紹介します.

1. 標準ライブラリ

当たり前ですが, 2.7で新しく入ったライブラリは2.6にはありません. しかし PyPIを探せば, 同等品があるはずです.

例えば, collections.OrderedDictの場合は, ordereddictがあるので,

try:
    from collections import OrderedDict
except ImportError
    from ordereddict import OrderedDict

とすれば, 2.6でも動きます.

他にも, argparseやunittestの新機能(PyPIではunittest2)などが該当します.

2. with文

2.7(や, 3.x)では, with文に複数の as を書くことができます.

with open("a.txt") as fa, open("b.txt") as fb:
    # faとfbを処理…

これは, 2.6にはありません. 代わりに, contextlib.nestedを使います.

from contextlib import nested

with nested(open("a.txt"), open("b.txt")) as (fa, fb):
    # faとfbを処理…

3. 辞書内包表記

{i:2**i for i in range(10)}

辞書内包表記は, 2.6用のコードでは, dict()を使うよう気をつけましょう.

dict(i:2**i for i in range(10))

4. 文字列format

2.7では文字列フォーマットの, 番号を省略できます.

'{}-{}.txt'.format(3, 14) # => '3-14.txt'

しかし, 2.6では番号は省略出来ません. 必ず明示的に各必要があります.

#2.6互換な書き方. 番号を明示する.
'{0}-{1}.txt'.format(3, 14) # => '3-14.txt'

辞書内包表記と違って, formatを間違えた時は, シンタックスエラーにならないので注意が必要です.

ただし, そもそも番号で指定するよりも, キーワード引数で指定し, その値が何を表すのか明示したほうが良いかも知れません.

#ベターな書き方. これも2.6互換
'{month}-{day}.txt'.format(month=3, day=14) # => '3-14.txt'

2.5との後方互換

2.5と3.xの両方で動くコードを書くのは困難です.

なぜなら,

from __future__ import unicode_literals

が動かないので, 文字列関係で大規模な変更が必要になるかもしれません.

2.5〜2.7の互換性に限るならば, 2.5では使えないprint関数など避けて, ライブラリもPyPIからインストールすれば可能です.

またwith文も,

from __future__ import with_statement

とすれば, 2.5でも使用可能です.