Python 2.5環境で動かすプログラムを作成する際の留意点のまとめ。
主にPython 2.5で使えない機能(モジュール・ビルドイン機能)と、その対策(代替機能)について。
※本記事で紹介しているのは一部のみで、他にも色々あります
モジュール
Python 2.5で使用できないモジュール群と代替機能について。
stringモジュール
stringモジュール自体は2.5でも使用できるが、string.Formatterクラスが使用できない。
7.1. string — Common string operations — Python 2.7.11 documentation
7.1.2. String Formatting
New in version 2.6.
message = "<format>".format(<parames>)
というようなformat関数の呼び出しはできない。
対策
旧式のformatting方式をつかう。
message = "hogehoge %d %s" % (123, "test")
argparseモジュール
New in version 2.7.
The argparse module makes it easy to write user-friendly command-line interfaces. The program defines what arguments it requires, and argparse will figure out how to parse those out of sys.argv. The argparse module also automatically generates help and usage messages and issues errors when users give the program invalid arguments.
対策
optparseモジュールを使う
15.5. optparse — Parser for command line options — Python 2.7.11 documentation
New in version 2.3.
optparse is a more convenient, flexible, and powerful library for parsing command-line options than the old getopt module. optparse uses a more declarative style of command-line parsing: you create an instance of OptionParser, populate it with options, and parse the command line. optparse allows users to specify options in the conventional GNU/POSIX syntax, and additionally generates usage and help messages for you.
optparseはPython 2.5にデフォルトで入っている。argparseと比較すると使いにくい。
argparseとoptparseの差については以下が詳しい。
argparse vs. optparse — argparse v1.1 documentation
argparseパッケージをインストールする
独立したパッケージとしてargparseがあるため、これをインストールする。
https://pypi.python.org/pypi/argparse
Compatibility
argparse should work on Python >= 2.3, it was tested on:
- 2.3, 2.4, 2.5, 2.6 and 2.7
- 3.1, 3.2, 3.3, 3.4
argparseパッケージ自体はPython 2.5もサポートしている。
multiprocessingモジュール
16.6. multiprocessing — Process-based “threading” interface — Python 2.7.11 documentation
New in version 2.6.
multiprocessing is a package that supports spawning processes using an API similar to the threading module. The multiprocessing package offers both local and remote concurrency, effectively side-stepping the Global Interpreter Lock by using subprocesses instead of threads. Due to this, the multiprocessing module allows the programmer to fully leverage multiple processors on a given machine. It runs on both Unix and Windows.
対策
threadingモジュールを使う
16.2. threading — Higher-level threading interface — Python 2.7.11 documentation
This module constructs higher-level threading interfaces on top of the lower level thread module. See also the mutex and Queue modules.
IO intensiveなプログラムだとthreadingでもマルチスレッド化することは有効。
一方で、CPU intensiveなプログラムだと、threadingはmultiprocessingの代替とならない。
multiprocessingだとマルチスレッド化するとCPU負荷は複数のコアに分散する。
しかし、threadingだと1コアに負荷が集中するため、マルチスレッド化しても効果は薄い。
multiprocessingパッケージをインストールする
Python 2.5用にバックポートされたモジュールがある。
Backport of the multiprocessing package to Python 2.4 and 2.5
jsonモジュール
18.2. json — JSON encoder and decoder — Python 2.7.11 documentation
New in version 2.6.
対策
simplejsonパッケージをインストールする
simplejson is a simple, fast, complete, correct and extensible JSON http://json.org encoder and decoder for Python 2.5+ and Python 3.3+. It is pure Python code with no dependencies, but includes an optional C extension for a serious speed boost.
simplejsonのインターフェースはjsonモジュールと同じ。
itertoolsモジュール
itertools自体はPython 2.5で使用できるものの、一部関数が2.6以降で追加されている。
9.7. itertools — Functions creating iterators for efficient looping — Python 2.7.11 documentation
New in version 2.3.
itertools.permutations(iterable[, r])
Return successive r length permutations of elements in the iterable.
New in version 2.6.
itertools.product(*iterables[, repeat])
Cartesian product of input iterables.
New in version 2.6.
対策
特に無し。
これは諦めるしかない?
collectionsモジュール
collections.Mapping
が使えない。公式ページを見ても2.5の時点で使えそうにみえるが・・・
8.3. collections — High-performance container datatypes — Python 2.7.11 documentation
New in version 2.4.
isinstance({}, collections.Mapping)
をPython 2.5で実行すると失敗する。
Python 2.7では成功する。
# python
Python 2.5.2 (r252:60911, Jan 24 2010, 14:53:14)
[GCC 4.3.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import collections
>>> isinstance({}, collections.Mapping)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'Mapping'
>>>
# python
Python 2.7.3 (default, Jan 2 2013, 16:53:07)
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import collections
>>> isinstance({}, collections.Mapping)
True
>>>
対策
isinstanceで使用する場合に限ってはisinstance({}, dict)
とするか、isinstanceを使わないことで対応できる。
collections.Mappingを継承するクラスを作りたい場合は諦める。
以下、isinstanceに関する対策。
この問題に直面した人の投稿がある。
google app engine - Python 2.5 version of this method - Stack Overflow
I have the below function running fine on python 2.6, but appengine's production environment is 2.5 and it blows up on:
AttributeError: 'module' object has no attribute 'Mapping'
Does anyone have a solution for 2.5?
回答では、isinstance(val, dict)
を使いなさい。
というものと、isinstanceを使うのをやめなさい。という回答がある。
- Try to stop using isinstance! – David Heffernan Feb 20 '11 at 15:59
- Or get rid of isinstance calls completely, since they are the enemy of duck typing. – Xiong Chiamiov Feb 20 '11 at 17:53
isinstanceはdock typingの敵である、というコメントはどういう意味か。
dock typingとは
まつもと直伝 プログラミングのオキテ - まつもと直伝 プログラミングのオキテ 第4回(3):ITpro
あるオブジェクトがどのクラスに所属するオブジェクトかは一切考慮せず,どのように振る舞うか(どのようなメソッドを持つか)だけに関心を払うのがDuck Typingです。Duck Typingを言い出したのは「達人プログラマ」として知られるDave Thomasです。
実際にDuck Typingをするにはどうすればいいか
では,動的型の言語でDuck Typingを実践するにはどのような指針に従えばよいのでしょうか。基本的な原則はたった1つ,最低限これだけを覚えておけば大丈夫です。
●明示的な型チェックを避ける
isinstanceはこれに反しているというわけですね。
isinstanceを使わないようにする
にはどういうコードを書けばいいか。
具体例を探してみると、あった。
Error importing 'Mapping' with Python 2.5 · Issue #8 · django-nonrel/django-dbindexer
isinstanceの代わりに try - except で判定している。
six
最新版ではなく、1.8.0を使用する。
詳細はPython2.5でsixを使う際の注意点 - Qiitaを参照。
Voluptuous
Python2.5でVoluptuousをインストールする - Qiitaを参照。
Pythonビルトイン機能
withキーワード
↓のようなコードは普通にPython 2.5で実行するとエラーになる。
with open("hoge", "w") as fp:
fp.write("foo")
# python --version
Python 2.5.2
# python with_sample.py
with_sample.py:1: Warning: 'with' will become a reserved keyword in Python 2.6
File "with_sample.py", line 1
with open("hoge", "w") as fp:
^
SyntaxError: invalid syntax
対策
from __future__ import with_statement
をプログラムの先頭に記述する。
from __future__ import with_statement
with open("hoge", "w") as fp:
fp.write("foo\n")
# python with_sample.py
# cat hoge
foo
成功する。
from __future__ import <feature>
は先のバージョンで標準になった機能を過去バージョンで使用するためのもの。以下はその一覧。
28.11. future — Future statement definitions — Python 2.7.11 documentation
feature | optional in | mandatory in | effect |
---|---|---|---|
nested_scopes | 2.1.0b1 | 2.2 | PEP 227: Statically Nested Scopes |
generators | 2.2.0a1 | 2.3 | PEP 255: Simple Generators |
division | 2.2.0a2 | 3.0 | PEP 238: Changing the Division Operator |
absolute_import | 2.5.0a1 | 3.0 | PEP 328: Imports: Multi-Line and Absolute/Relative |
with_statement | 2.5.0a1 | 2.6 | PEP 343: The “with” Statement |
print_function | 2.6.0a2 | 3.0 | PEP 3105: Make print a function |
unicode_literals | 2.6.0a2 | 3.0 | PEP 3112: Bytes literals in Python 3000 |
asキーワード
except中にasを使うと失敗する。
try:
raise ValueError("hoge")
except ValueError as e:
print e
# python --version
Python 2.5.2
# python except_sample.py
except_sample.py:3: Warning: 'as' will become a reserved keyword in Python 2.6
File "except_sample.py", line 3
except ValueError as e:
^
SyntaxError: invalid syntax
同じプログラムでもPython 2.6以降では動く。
# python --version
Python 2.7.3
# python except_sample.py
hoge
対策
as
を,
に置換する。
try:
raise ValueError("hoge")
except ValueError, e:
print e
# python --version
Python 2.5.2
# python except_sample.py
hoge
ちなみにimport
やwith
キーワードはPython 2.5でもas
が使える。
from __future__ import with_statement
import simplejson as json
try:
raise ValueError("hoge")
except ValueError, e:
print e
with open("hoge", "r") as fp:
print fp.read()
# python --version
Python 2.5.2
# python as_sample.py
hoge
foo
ただし、これをやるとPython 3系では動作しなくなる。
Python 3でも互換性を保つためには以下。