Python 調査報告
動的なオブジェクト指向言語である
Python についての調査結果を報告する。報告内容は2006年10月現在の最新バージョンである
Python-2.5 に基いている。
Pythonは適用可能分野が幅広く、かつ言語仕様がシンプルであるため、一度覚えると便利な道具である。例えばゲーム、ネットワークプログラミング、クロスプラットフォームGUI、Webアプリケーション開発、システム管理等に向く。
Pythonは非常に実用的な言語である。丁寧にドキュメント化された拡張方法、モジュール化された言語仕様、パッケージ形式の標準化等により、世界中の開発者がパッケージを公開していることが一助となっている。インターネット上にある多種多様なリソースにアクセスしやすいよう、本報告書はHTML形式となっている。
まずはじめに、Pythonを使うと何ができるかの概略を示します。本報告書はある程度コンピューター言語を知っている人を対象に書かれています。他の言語を知らない人は、まずPythonの
チュートリアルに目を通すことをお勧めします。
Pythonを起動すると、インタープリタ(REPL, Read-Eval-Print Loop)として直接プログラムコードを入力できます。
> python
Python 2.5 (r25:51908, Sep 19 2006, 22:27:44)
[GCC 3.3.5 (Debian 1:3.3.5-13)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> print "Hello World!"
Hello World!
色違いの文字はキーボード入力です。このように、有名な "Hellow World!" を出力するプログラムは非常にシンプルです。もちろん、ソースコードを実行することもできます。python プログラムは実際にはコンパイラでもあり、ソースコードを自動的にコンパイルして実行します。
> more hello.py
print "Hello World!"
> python hello.py
Hello World!
Pythonはオブジェクト指向言語です。Java, C++ とは異なり、全ての値はオブジェクトです。整数や文字列などは不変(immutable)なオブジェクトです。
後述するように関数、型、さらにメタクラスさえもオブジェクトです。
> python
Python 2.5 (r25:51908, Sep 19 2006, 22:27:44)
[GCC 3.3.5 (Debian 1:3.3.5-13)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> type(3)
<type 'int'>
>>> type(3).__bases__
(<type 'object'>,)
>>> class MyInt(int):
... pass
...
>>> a = 3
>>> b = MyInt(3)
>>> a == b
True
>>> a * b
9
不変なオブジェクトの存在意義は、ハッシュ可能であることです。ハッシュ可能なオブジェクトは
ディクショナリ(連想配列)のキーとなれます。下の例ではタプルのハッシュ値を求めています。タプル自体は不変なオブジェクトですが、中に可変オブジェクトであるリストを含むと、ハッシュ可能ではなくなります。
>>> a = (3, 5)
>>> hash(a)
1698260191
>>> b = ([], "aaa")
>>> hash(b)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: list objects are unhashable
オブジェクト指向言語の種類としては、クラスベースとなります。が、クラスもオブジェクトであり、
メタクラスによってその挙動をカスタマイズすることもできます。様々な点で静的なクラスベースの言語のようには制約されません。例えば、オブジェクトのクラスは簡単に変更可能です。
>>> class Foo(object):
... def p(self):
... print "foo"
...
>>> class Bar(object):
... def q(self):
... print "bar bar"
...
>>> a = Foo()
>>> a.p()
foo
>>> isinstance(a, Foo)
True
>>> isinstance(a, Bar)
False
>>> a.__class__ = Bar
>>> isinstance(a, Bar)
True
>>> a.q()
bar bar
インスタンスの属性参照は、まずインスタンス自身を検索し、見つからなければそのクラスの属性、さらに見つからなければ親クラスの属性、と検索されます。クラスのメソッドも属性の一つにすぎないので、インスタンスが同名の属性を持てば呼び出されなくなります。
>>> class Foo(object):
... p = 3
...
>>> f = Foo()
>>> f.p
3
>>> f.p = 10
>>> f.p
10
>>> Foo.p
3
ここに示したような挙動は、Pythonの動作原理を知ることで簡単に理解可能です。Pythonは様々な機能を提供しますが、全てはシンプルなルールのもとで動作しているのです。例えば、組み込み関数は "__builtins__" というモジュール(オブジェクト)を参照しているので、"__builtins__" を置き換えることで組み込み関数をすげかえることができます。組み込み関数が予約されているということはありません。
>>> a = __builtins__
>>> def my_type(*args):
... print "hoge"
...
>>> type(a)
<type 'module'>
>>> __builtins__ = {'type':my_type}
>>> type(a)
hoge
Pythonの文法は、インデントと改行を強制します。Pythonはもともと教育用に作られたので、ドキュメントを重視し、コードも分かりやすくする文化があるようです。JavaやCに慣れた方は、最初はとまどうかもしれませんが、すぐに慣れます。コーディングスタイルを揃えることのメリットを理解していればね!
Pythonの言語仕様はシンプルです。これは Perl との大きな違いです。PerlのTIMTOWTDI哲学(There Is More Than One Way To Do It)は、あることに対して何種類もの記法・やり方を提供しています。この違いは、チームでの開発やメンテナンス性において Python を Perl よりも優位とするでしょう。PerlとPythonの比較で一例を挙げると、Perlの予約語が200を越すのに対し、
Pythonの予約語はわずか30語です。まとめると、
- 値は全てオブジェクト
- クラスベースの動的オブジェクト指向言語
- シンプルな(ルールに統治された)言語仕様
- 改行とインデントを強制する文法
Pythonはそれ自体でも多彩な機能を提供しますが、glue(糊)として利用されるケースも多いです。例えば
標準ライブラリには以下のような機能が含まれます。
拡張モジュールとしては以下のようなものがあります。
- mod_python, apacheにPythonを組み込み
- SciPy & NumPy, 科学技術計算ライブラリ
- Django, Webアプリケーションフレームワーク
- Twisted, イベント駆動型のネットワークアプリケーションフレームワーク
- PyGame, Gameフレームワーク
- py2exe, Pythonスクリプト&実行環境をまとめて実行形式にするツール
- PEAK, エンタープライズツールキット
- wxPython, wxWidgets クロスプラットフォームGUIツールキット
- Python Cheese Shop, オンラインモジュール集, distutils のアップロード先
Pythonが使われているものとしては以下のようなものがあります。
性能面ではJavaやC++等には大分劣りますが、Perl・PHP・Rubyと言った主要なスクリプト言語と比較すると速いことが分かります。また、
こちらでは、
PsycoのJIT(Just-In-Time Compile)機能による高速化の様子が見れます。(Psycoについては
こちらや
こちらの記事が詳しいです)
残念ながら、Pythonの日本における普及度はそれほど高くありません。この一つの理由は、日本語コーデックの標準搭載が比較的最近(Python-2.4)であったためだと思われます。そのような中でも、
日本Pythonユーザー会および
日本語訳は役に立つでしょう。
実際のコーディングの際には
pydoc が詳細なAPIを示してくれます。pydoc はPythonのソースコード中のドキュメント文字列(docstring)をHTML形式やテスト形式に整形して表示します。また
Python Quick Reference はPythonの様々な情報を簡潔に整理したリファレンスを提供しています。
Pythonはバージョンを追うごとに益々洗練され、便利になっています。最新の機能を知るには各バージョンの "What's New" ドキュメント(
2.3,
2.4,
2.5)にあたりましょう。本報告ではPython-2.3以降で知っておきたいポイントを
いくつか解説しています。
後述するように、Pythonの処理系はいくつかあり、処理系ごとに開発体制は異なっています。ですが、仕様策定の中心となる(リファレンス的な)実装としてCPythonがあり、一般に Pythonと言うとCPythonのことを指しています。
CPythonは元々は Guido van Rossum 氏(現Google)によって作られました。今でもGuido氏は開発の中心であり、BDFL(Benevolent Dictator For Life)とも呼ばれ、CPythonの言語仕様の決定権を持っています。
バージョン間の互換性も重視されています。バックワードコンパチビリティのみならず、フォワードコンパチビリティにも配慮されているのです。具体的には
__future__ によるコンパチビリティ制御機能を参照してください。
CPythonのバージョン番号は三つ組で表現され、三番目は(主に)バグフィックスのためのリビジョン番号となっています。
Pythonの言語自体については、各種の本やドキュメントを参照してください。ここでは、特に興味を引きそうなトピックに焦点を絞って解説します。
Pythonソースファイルから、他のPythonソースファイルを import すると、
モジュールオブジェクトが取得できます。ソースコードのトップレベルで定義した識別子は、モジュールオブジェクトの属性となります。C言語のように大域変数にはなりません。
> more > test.py
a = 3
> python
Python 2.5 (r25:51908, Sep 20 2006, 12:09:43)
[GCC 3.4.3 20050227 (Asianux 2.0 3.4.3-22.1.1)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import test
>>> print test
<module 'test' from 'test.py'>
>>> test.a
3
Pythonは
関数の呼び出し方式として、位置指定の引数(positional arguments)以外に名前指定の引数(keyword arguments)もサポートします。
>>> def hoge( a, b = 2, c = 3 ):
... print a, b, c
...
>>> hoge( 1 )
1 2 3
>>> hoge( 1, 5 )
1 5 3
>>> hoge( 1, c = 10 )
1 2 10
位置指定の引数は *args としてリスト形式で渡すことも可能です。同様に名前指定の引数は **args としてディクショナリ形式で渡すことも可能です。
>>> args = [ 100, 1000 ]
>>> hoge( *args )
100 1000 3
>>> args = { 'a':100, 'c':1000 }
>>> hoge( **args )
100 2 1000
同様の形式で仮引数を宣言すると、リスト形式または辞書形式でオプショナルな引数を受け取ることができます。
>>> def fuga( a, b = 2, *arg_list, **arg_dict ):
... print arg_list, arg_dict
...
>>> fuga( 3 )
() {}
>>> fuga( 3, 2, 1 )
(1,) {}
>>> fuga( 3, 2, 1, c = 5 )
(1,) {'c': 5}
Pythonの演算子(<, >, ==, %, +, abs() など)の多くは、特殊メソッドによってオーバーライド可能です。標準の型でも、シーケンスの '+' や文字列型の '%' などが特殊メソッドによって実装されています。
>>> "line %d reads %s" % (3, 'hoge')
'line 3 reads hoge'
>>> "line %d reads %s".__mod__( (3, 'hoge') )
'line 3 reads hoge'
(関数の)呼び出し演算も特殊メソッドによって実装できます。下に示す
__call__ メソッドを提供するオブジェクトのことをPythonでは「呼び出し可能(callable)」オブジェクトといいます。
>>> class Hoge(object):
... def __call__(self, *args):
... return reduce(__import__('operator').mul, args)
...
>>> h = Hoge()
>>> h(3, 5, 6)
90
>>> callable(hoge)
True
前節で解説した通り、関数は呼び出し可能なオブジェクトの一種です。このオブジェクトは可変で、任意の属性を持たせることができます。
>>> def fuga():
... print 'fuga'
...
>>> callable(fuga)
True
>>> fuga.a = 3
>>> fuga.a
3
メソッドも関数と同じようにオブジェクトです。このように全てがオブジェクトであることから、関数やメソッドを
一級(first class)に扱えます。ハンドラとしてメソッドや関数をその場で渡せるため、PythonにおけるGUIプログラミングは関数型言語のように簡潔に記述できます。下に示すサンプルは
wxPython のコード例です。
>>> import wx
>>> class MyFrame(wx.Frame):
... def __init__(self, parent):
... super(MyFrame, self).__init__(parent, -1)
... self.Bind(wx.EVT_CLOSE, self.OnCloseMe)
... self.Show()
... def OnCloseMe(self, event):
... print 'hoge'
... self.Destroy()
...
>>> app = wx.PySimpleApp()
>>> frame = MyFrame(None)
>>> app.MainLoop()
hoge
前項で紹介したように、Pythonではオブジェクトの振舞いのほとんどはメソッドの実装によって定義できます。例えば数値のように振舞うオブジェクトを作りたければ、数値クラスが持つべきメソッドを持つクラスを定義すれば良いのです。数値以外にもシーケンス、ディクショナリ、イテレータといった型を、メソッドを定義することでエミュレートできます。こういったプログラミングスタイルのことを
Duck Typingと言います。
例えば標準モジュールの
StringIO は、ファイルオブジェクトと互換の StringIO クラスを提供します。ですが、ファイルオブジェクトと StringIO クラスは(objectを除いて)共通する型を持つわけではありません。
Duck Typing はコードに柔軟性を与える点では優れています。反面、定義するべきメソッドを明確にしないため、暗黙の約束事を常に意識する必要があります。この欠点を克服する試みとしては
Zope Interfaces があります。Zope Interfaces はオブジェクトが備えるべき挙動を記述し、チェックできる機構を提供します。Javaのインターフェースと違って、このインターフェースは予め実装するだけではなく、後から宣言することも可能です。
Pythonのオブジェクトには二通りの振舞いが存在します。一つはクラシックなクラスと呼ばれ、Python-2.2以前はこちらしか利用できませんでした。Python-2.2からは、
新しいスタイルのクラスが利用できます。新しいスタイルのクラスの特徴は
ドキュメントを参照してください。
>>> class A:
... pass
...
>>> a = A()
>>> class B(object):
... pass
...
>>> b = B()
>>> type(A)
<type 'classobj'>
>>> type(B)
<type 'type'>
>>> type(a)
<type 'instance'>
>>> type(b)
<class '__main__.B'>
チュートリアルにおけるクラスの説明は現在新しいスタイルのクラスに言及していませんが、これから作成するプログラムは必ず新しいスタイルで作成するべきです。全ての組み込みデータ型は、新しいスタイルのクラスです。ですので組み込み型のサブクラスを作成して拡張することができます。
>>> class MyList(list):
... pass
...
>>> type(MyList)
<type 'type'>
新しいスタイルのクラスで利用できるようになった、
スタティックメソッドや
プロパティといった機能は
Descriptors によって実現されています。Descriptorsは属性参照を制御できるオブジェクト単位の機構です。従来のクラスではクラスの特殊メソッド(__getattr__, __setattr__, __delattr__)を実装することで属性参照を制御していましたが、Descriptorsは属性オブジェクトごとに挙動を制御できるのでより柔軟です。
>>> class C(object):
... def getHoge(self):
... return 10
... hoge = property(getHoge, doc = 'hoge')
...
>>> c = C()
>>> c.hoge
10
>>> C.hoge
<property object at 0xb7d2f414>
>>> dir(C.hoge)
['__class__', '__delattr__', '__delete__', '__doc__', '__get__',
'__getattribute__', '__hash__', '__init__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__set__', '__setattr__', '__str__',
'fdel', 'fget', 'fset']
>>> C.hoge.__get__(c)
10
メタクラスとは、クラスの型のことです。オブジェクトの挙動をクラスが規定するように、クラスの挙動はメタクラスで規定されます。前項で示したように、新しいスタイルのクラスの場合は 'type' になります。
例えば、クラス属性を自動的にインスタンス属性の初期値とするようなメタクラスは以下のようになります。この例では元々の __init__() メソッドを拡張する内部関数 init() を定義し、__init__() を置き換えています。
>>> class MyMeta(type):
... def __init__(cls, name, bases, dict):
... original = dict.get('__init__', None)
... def init(self, *args, **kwargs):
... for (kw, value) in dict.iteritems():
... if callable(value):
... continue
... setattr(self, kw, value)
... if original is not None:
... original(self, *args, **kwargs)
... setattr(cls, '__init__', init)
...
>>> class Hoge:
... __metaclass__ = MyMeta
... x = 3
... y = 10
... def __init__(self, msg):
... print msg
...
>>> h = Hoge('fuga')
fuga
>>> vars(h)
{'y': 10, 'x': 3, '__module__': '__main__'}
CPythonの最近のバージョンで追加された機能から、個人的なお勧めをいくつか紹介します。
- enumerate
シーケンスに対して for ループを回す際に、インデックスが必要になるケースは多々あります。enumerate を使えば、インデックスを簡潔に取得できるようになります。
>>> l = ['apple', 'pine', 'cherry', 'orange']
>>> for i, fruit in enumerate(l):
... print "No.%d: %s" % (i, fruit)
...
No.0: apple
No.1: pine
No.2: cherry
No.3: orange
- logging
logging パッケージは標準で組み込まれていますが、拡張性が高く、柔軟に様々なケースに対応できます。自前のログ機構の前に、この標準モジュールの使用を検討しましょう。
- built-in set
データ型として集合を使用することはよくありますが、Python-2.4からは set 型が組み込まれています。
- python -m MODULE_NAME
Pythonインタープリタは 2.4 から -m というオプションでモジュールファイルをメインスクリプトとして起動することができるようになりました。この機能のお陰で、デバッガ、プロファイラ、コンパイラといったモジュールをコマンドラインから直接起動できるようになりました。
> python -m pdb
usage: pdb.py scriptfile [arg] ...
2.4以前では以下のように記述する必要がありましたので、格段にユーザビリティが向上しています。
> python
Python 2.5 (r25:51908, Sep 19 2006, 22:27:44)
[GCC 3.3.5 (Debian 1:3.3.5-13)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import pdb
>>> import hoge
>>> pdb.run('hoge.hoge()')
> <string>(1)<module>()
(Pdb) n
aaa
- Generator Expressions
リストの内包とほとんど同様の記法で、Generatorを作成することができます。実体のリストを作成する必要がない場面では Generator Expressions のほうがメモリの使用効率が良いです。下のように関数呼び出しの内側にも記述できます。
>>> ", ".join( str(x) for x in xrange(10) )
'0, 1, 2, 3, 4, 5, 6, 7, 8, 9'
- デコレータ
スタティックメソッドなどは従来は staticmethod() 関数でメソッドをラップして定義する必要がありました。
>>> class Hoge(object):
... def fuga():
... print 'fuga'
... fuga = staticmethod(fuga)
...
>>> Hoge.fuga()
fuga
2.4からは、staticmethod()やclassmethod()のように元々の関数をラップする関数を、関数定義の前に宣言する記法が追加されました。以下のように "@FUNCTION" を def 文の前に配置すると、def で定義される関数が "FUNCTION" で自動的にラップされます。
>>> class Hoge(object):
... @staticmethod
... def fuga():
... print 'fuga'
...
>>> Hoge.fuga()
fuga
- Conditional Expressions
Cの三項式といえば、"EXPR_TEST ? EXPR_TRUE : EXPR_FALSE" でお馴染みの条件演算子のことです。条件に応じて変わる値のみ必要な場合、if 文では冗長と考えて条件演算子を使用する人も多いでしょう。Python-2.5からPythonでも条件演算子が利用できるようになりました。ただし C とは違い、"EXPR_TRUE if EXPR_TEST else EXPR_FALSE" という記法になっています。
>>> def numerize(x):
... return x if type(x) is int else 1
...
>>> numerize(100)
100
>>> numerize(False)
1
>>> numerize('hoge')
1
- with
開いたファイルを閉じるように、後処理が必要な場面は多々あります。Python-2.5以前には、例外機構に関わらず後処理を確実に実行させる用途で try ... finally ブロックを使用していました。2.5からは with 文も利用できます。
>>> from __future__ import with_statement
>>> with open('/etc/passwd', 'r') as f:
... for line in f:
... if len(line) < 30:
... raise Exception('too short line: ' + line)
...
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
Exception: too short line: bin:x:2:2:bin:/bin:/bin/sh
>>> f
<closed file '/etc/passwd', mode 'r' at 0xb7d02ad0>
withに対応していないオブジェクトでは利用できないのが難点ですが、contextlib.closing()などのラッピング関数を利用できます。堅牢なコーディングには役に立ちますので、積極的な使用をお勧めします。
処理系の一覧に、現在ある処理系がリストされています。最も良く使われている処理系は CPython です。CPythonの
メモリ管理は基本的にはリファレンスカウントですが、サイクルを見付けるためにトラバース処理もなされます。
独立した処理系ではないのですが、
PsycoはCPythonの拡張モジュールとしてJIT機能を提供します。現在のところは x86 CPU 限定です。
他言語との比較でもPsyco関連の情報を解説しています。
Stackless Pythonはネイティブなスレッドの代わりにマイクロスレッドを使用するCPythonから派生した処理系です。並列計算を便利にしてはくれますが、CPythonと非互換な点もあります。Cスタックを使わないためCPythonより約10%高速である点などを活かして、
MMO RPGなどで使用されています。
JythonはJavaに埋め込める実装です。Javaと良く結合されており、Javaのオブジェクトを利用できます。CPythonの 2.1 相当の機能を実装しており、CPythonが 2.5 であることを考えると開発は遅いと言えるでしょう。メモリ管理は JVM に任せています。
主要なトピックをカテゴリー別に解説します。特に触れない限り、CPythonを前提としています。
コンパイル、ドキュメンテーション、テスト、デバッグ、プロファイリングといった開発補助機能は標準で提供されています。
コンパイル
Pythonはソースコードを中間コードに
コンパイルしてから実行します。コンパイル結果は .pyc (もしくは .pyo) という拡張子のファイルに保存されます。現在のところ、最適化(python -O)は assert 文を除去する効果しかないようです。
python [-O] -m py_comile *.py
python [-O] -m compileall DIR
ドキュメンテーション
Pythonのモジュールや関数、クラスなどは
docstring というドキュメント属性を持つことが可能です。docstring の最初の行は大文字から始めて簡潔に動作を記述します。さらに詳細を記述する場合は2行目は空行とし、3行目から内容を記述するようにします。
def numerize( x ):
'''Return the argument if it is integer; otherwise returns 1.
Arguments:
x: any object to be numerized.
'''
return x if type(x) is int else 1
Pythonのソースコードドキュメンテーションは
pydoc モジュールによって処理されます。UNIX環境では pydoc と同名のコマンドもインストールされます。pydoc はHTMLかテキスト形式のドキュメントを生成します。また簡易なGUIも備えており、"pydoc -g" で利用できます。
> pydoc hoge.numerize
Help on function numerize in hoge:
hoge.numerize = numerize(x)
Return the argument if it is integer; otherwise returns 1.
Arguments:
x: any object to be numerized.
テスト
doctestはコメント(docstring)に書いた用例が正しいことを検証します。xUnit系の単体テストであれば、
unittestフレームワークを使います。
デバッグ
pdbモジュールがデバッガの機能を提供します。pdbはコマンドラインインターフェースも提供します。
python -m pdb *.py
プロファイリング
Python Profilersにプロファイリングに関する情報がまとまっています。Python-2.5からは負荷を軽くするためにCで作成された cProfile モジュールも提供されています。cProfile(profile)はコマンドラインインターフェースも提供します。
python -m cProfile hoge.py
10004 function calls in 0.018 CPU seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.018 0.018 <string>:1(<module>)
1 0.010 0.010 0.018 0.018 hoge.py:3(<module>)
10000 0.008 0.000 0.008 0.000 hoge.py:3(numerize)
1 0.000 0.000 0.018 0.018 {execfile}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
DB-API 2.0という標準があり、ほとんどのデータベースドライバはこの標準に準拠しています。ODBC, JDBC のようなものです。
MySQLであれば、
MySQL for Pythonを使うのが良いでしょう。MySQL-5.0まで対応しています。Prepared Statement は現時点ではエミュレーションでの対応です。
Object Relational マッピングには
SQLAlchemyが良く使われています。SQLAlchemyはORマッピングで良く問題になる点(JOINやサブクエリへのマッピング、クエリチューニングなど)に対応できるように設計されています。
Pythonでは8bit文字列とユニコード文字列は型として分かれています。国際化するにあたってはユニコード文字列を使用することになるでしょう。様々なエンコーディング方式には
codecs を通してアクセスしてください。特に有用なのは、'codecs.open()' です。open() と同様に使えますが、文字コードを透過的に変換します。
>>> f = codecs.open('abc', 'w', 'shift_jis')
>>> f.write(u'あいうえお')
>>> f.close()
文字列カタログとしてはUNIXのgettext互換の
gettext モジュールが存在します。
TkInter が標準的なGUIライブラリとして提供されていますが、できあがるアプリケーションのUIは「そこそこ」にとどまります。
その他、様々なGUIライブラリモジュールが存在しますが、一番のお勧めは
wxPython です。クロスプラットフォームで、OSネイティヴのコントロールを使うため、洗練されたUIを作れます。ドキュメントがオンラインでは整備されていないのが困ったところですが、幸いほぼ最新の wxPython を解説した
本が発売されています。
Pythonには標準でも基本的なXMLやHTML処理用のライブラリが
付属しています。さらに高機能なパーザー群が必要であれば、
PyXMLや
4Suiteを導入しましょう。後者ではXSLTやRelaxNGの処理も可能です。
CPythonをC言語で拡張するにはいくつか方法があります。もっとも基本的な方法は
C APIを利用して拡張モジュールを作成するか、C言語にインタープリタを埋め込むものです。単純にシステムのライブラリを呼び出すだけであれば、Python-2.5から標準になった
ctypes モジュールを利用できます。
C言語で拡張モジュールを作成する方法としてはもっと簡便な方法もあります。
Swigは既存のライブラリに対する
Pythonラッパーを作成する場合に便利でしょう。
PyrexはPythonに似た文法で拡張モジュールを作成できるツールです。Swig, Pyrex のいずれも、C言語のソースコードを生成します。
標準化されている
distutils によって、簡単にソースパッケージを作ることができます。PEAKの
setuptools は distutils の拡張で、
egg という1ファイル形式(JavaのJARファイルのようなもの)での配布や、前述の
Pyrexなどをサポートします。setuptools は distutils の上位互換であるため、setuptools を使用しない理由はありません。積極的に使用しましょう。
ゲームなど、実行可能形式として配布したいときには
py2exe や
cx_Freeze を利用できます。どちらも簡単に使えるでしょう。py2exeを使えばWindowsサービスやCOMサーバーを作ることもできます。
一般的な注意として、配布の際にはバンドルされるモジュールのライセンスに注意しましょう。特に、py2exeは(と言うよりも http://www.python.org/ で配布されるWindows版Pythonは) MSVCR71.dll をバンドルします。これは
Visual Studio .NET 2003 の再配布モジュールですので、配布に際しては Visual Studio .NET 2003 を購入している必要があります。
CPythonに標準でついている IDLE は、簡素ながらコードエディタにデバッガを統合した開発環境を提供します。お勧めは Eclipse Plugin の
PyDev です。コード補完、デバッグ等が CPython, Jython 両方で可能です。
IronPython は Visual Studio に統合することができます。
こちらの記事を参考にしてください。その他にも色々なIDEがあります。こちらの
評価記事が参考になるでしょう。
改訂:2006年10月17日
- 事例に Xen の管理ツール virt-manager を追加
- 開発環境に IPython を追記
- 関数やメソッドが一級のオブジェクトであることを追記
- XML処理の項目を追加
- その他、こまごまと修正、追記
本改訂に際しては
Python-ml-jpより Kazuo Moriwaka 氏、メールにて
西尾泰和氏よりいただいたご意見を参考にしました。心より感謝いたします。
初版:2006年10月10日
Copyright © 2006 Cybozu Inc., All rights reserved.