pythonのソースコードを読むコツのようなもの
2007/09/20 追記。以下で色々頑張ってるようなこと全部IPythonで出来るみたい...orz
まだまだ駆け出しなりに連日試行錯誤してわかってきたことがあるので書いておく。
これからpythonはじめる人とかの参考になればうれしい。
それは違うだろ?っていうpythonistaの方の突込みがあるとさらにうれしい。
道具重要!!
pythonインタプリタ
rlcompleterとreadlineが使えるようにしておくのがお勧め。
import rlcompleter, readline
でエラーでないならOK。やり方は以前書いたので省略。
IPythonがお勧めらしいけど結局使ってない...。
pydoc
モジュールや関数、クラス、インスタンスメソッドなどのサマリを手っ取り早く参照したい時に使うようにするつもり。
ちょっと調べたいだけならターミナル上で
% pydoc sys
>>> import sys >>> help(sys)
するのが簡単で楽。小中規模のソースコードの全体像を俯瞰してみたい場合はpydocがいいと思う。
標準モジュールなどはhttp://pydoc.org/にあった。
使い方はhttp://pydoc.org/2.4.1/pydoc.html
日本語ならhttp://www.python.jp/doc/2.4/lib/module-pydoc.html
inspect
便利すぎる。まじで。もはやこれなしで過ごせなくなりつつある。
これはpython本気で勉強しだして以来最大の収穫といっても過言じゃないかもしれない。
個人的にはこれを知ったおかげで世界が変わった。
オンラインドキュメント最初にちゃんと読めという話はおいといて...
何がすごいってpythonインタプリタ上からピンポイントで各種ライブラリの実装を取得できるのが個人的に便利すぎる。
実行例
- django.db.models.base.Model#__eq__の実装を調べる
- 上記実装で呼んでいるdjango.db.models.base.Model#_get_pk_val()の実装を調べる
- django.db.models.base.Model#_get_pk_val()がどのファイルに定義されているか調べる
- django.db.models.base.Model#_get_pk_val()が何行目に定義されているか調べる
上記を調べたい場合に以下のようにすると簡単に調べられる。
>>> import inspect >>> from django.db.models.base import Model >>> print inspect.getsource(Model.__eq__) def __eq__(self, other): return isinstance(other, self.__class__) and self._get_pk_val() == other._get_pk_val() >>> print inspect.getsource(Model._get_pk_val) def _get_pk_val(self): return getattr(self, self._meta.pk.attname) >>> print inspect.getfile(Model._get_pk_val) /usr/lib/python2.4/site-packages/django/db/models/base.py >>> array = inspect.getsourcelines(Model._get_pk_val) >>> print array[1] 83
さらに補完とはいえ毎回似たようなのを打つのが面倒なら全てがオブジェクトなのを利用して
>>> igf = inspect.getfile >>> print igf(Model._get_pk_val) /usr/lib/python2.4/site-packages/django/db/models/base.py
とか出来る。んでこの辺りの初期設定を以前pythonインタプリタでのメソッド名の補完で書いた~/.pythonrc.pyに追記してみた。
import rlcompleter, readline readline.parse_and_bind('tab: complete') import inspect igd = inspect.getdoc igs = inspect.getsource igf = inspect.getfile igsl = inspect.getsourcelines
で、試してみると
>>> ig igd igf igs igsl >>> igd(igf) 'Work out which source or compiled file an object was defined in.' >>> print igs(igf) def getfile(object): """Work out which source or compiled file an object was defined in.""" if ismodule(object): ...中略
うん、これでちょっとははかどるようになるかなぁ。強いて不満点を上げるとすればソースコードハイライトがないことくらいかな。
まぁがっつり読むときはvimで読むからいいか。
pdb
正直まだしっかり使ってないけれど実際に実行しながらソースコード読むときに重宝しそう。詳細はたぶん書かない。
http://0xcc.net/blog/archives/000162.html
ここで色々書いてあるのでこれを後で読んで試す(たぶん)