組み込み関数dir()をカスタマイズする
「初めてのPython」p.344に載っていたdir()のような動作をするソースがなかなか良い感じです。
#!usr/bin/env python # -*- coding: utf-8 -*- """ mydir.py 組み込み関数dir()をカスタマイズする例 指定のモジュールの名前空間に属する変数名の一覧を出力する """ verbose = 1 def listning(module): if verbose: print "-" * 30 print "name:", module.__name__, " file:", module.__file__ print "-" * 30 count = 0 for attr in module.__dict__.keys(): # 名前空間の内容を調べる print "%02d) %s" % (count+1, attr), if attr[0:2] == "__": # __で始まる属性はビルトイン print "<built-in name>" # ビルトイン属性の出力 else: print getattr(module, attr) # .__dict__[attr]と同等 count += 1 if verbose: print "-" * 30 print module.__name__, "has %d names" % count print "-" * 30 if __name__ == "__main__": import mydir listning(mydir) # トップレベルファイルとして実行した場合、自身を引数とする
実行すると・・・
$ python mydir.py ------------------------------ name: mydir file: /Users/ama-ch/python/mydir.py ------------------------------ 01) listning <function listning at 0x6e770> 02) verbose 1 03) __builtins__ <built-in name> 04) __file__ <built-in name> 05) __name__ <built-in name> 06) __doc__ <built-in name> ------------------------------ mydir has 6 names ------------------------------
こんな感じで属性とその性質の一覧が出力できます。dir()を使うよりも見やすいですね。
同じmydirをdir()で見ると・・・
>>> import mydir >>> dir(mydir) ['__builtins__', '__doc__', '__file__', '__name__', 'listning', 'verbose']
これだけだとよくわからないし、数が増えてくると読みにくくなります。
標準ライブラリもmydirで見てみよう。
・math
>>> import mydir >>> import math >>> mydir.listning(math) ------------------------------ name: math file: /Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/lib-dynload/math.so ------------------------------ 01) pow <built-in function pow> 02) cosh <built-in function cosh> 03) ldexp <built-in function ldexp> 04) hypot <built-in function hypot> 05) tan <built-in function tan> 06) asin <built-in function asin> 07) log <built-in function log> 08) fabs <built-in function fabs> 09) floor <built-in function floor> 10) sqrt <built-in function sqrt> 11) frexp <built-in function frexp> 12) degrees <built-in function degrees> 13) pi 3.14159265359 14) log10 <built-in function log10> 15) __doc__ <built-in name> 16) fmod <built-in function fmod> 17) atan <built-in function atan> 18) __file__ <built-in name> 19) ceil <built-in function ceil> 20) sinh <built-in function sinh> 21) __name__ <built-in name> 22) cos <built-in function cos> 23) e 2.71828182846 24) tanh <built-in function tanh> 25) radians <built-in function radians> 26) sin <built-in function sin> 27) atan2 <built-in function atan2> 28) modf <built-in function modf> 29) exp <built-in function exp> 30) acos <built-in function acos> ------------------------------ math has 30 names ------------------------------
piやeの値もわかります。
・sys
>>> import sys >>> mydir.listning(sys) ------------------------------ name: sys file: Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/Users/ama-ch/python/mydir.py", line 13, in listning print "name:", module.__name__, " file:", module.__file__ AttributeError: 'module' object has no attribute '__file__'
ありゃ、ダメだ。どうやらsys.__file__というメンバがないらしい。
う〜ん、モジュールの実体がないってこと?でもインポートしてるんだからあるはず。
調べてみた
定義済みの (書き込み可能な) 属性: __name__ はモジュールの名前です; __doc__ は関数のドキュメンテーション文字列です。ドキュメンテーションがない場合は None になります; モジュールがファイルからロードされた場合、 __file__ はロードされたモジュールファイルのパス名です。インタプリタに静的にリンクされている C モジュールの場合、__file__ 属性はありません; 共有ライブラリから動的にロードされた拡張モジュールの場合、この属性は共有ライブラリファイルのパス名になります。
3.2 標準型の階層 - モジュール
Cで書かれたモジュールは__file__メンバがないという解釈でいいのかな?
そういえば
現在のところリロードが可能なのはPythonで書かれたモジュールのみであるという点です。Cで書かれたエクステンションモジュールなどは、リロードができないのです(インポートはPythonで書かれたモジュールと同じようにできる。)
「初めてのPython」 p.321
こんなことも書いてあったけど、これも関係してるんだろうか。でも初めてのPython結構情報が古いからなぁ。。。また調べる。