参考までに - getclasstree関数の動作
参考までに、inspectモジュールgetclasstree関数について調べた内容を記しておく。
以下のようなテストクラスを用意して
テストクラス
import inspect class MyClsA(object): pass class MyClsAS(MyClsA): pass class MyClsASS(MyClsAS): pass class MyClsASSS(MyClsASS): pass class MyClsB(object): pass class MyClsABS(MyClsA,MyClsB): pass class MyClsAS2(MyClsA): pass
MyClsAのサブクラスであるMyClsASについてgetclasstree関数の戻り値を表示してみる。
例1-MyClsAS
classtree=inspect.getclasstree([MyClsAS]) print classtree
結果をみやすいようにインデントや改行を追加して整形してみると
実行結果
[ ( <class '__main__.MyClsA'>, ( <type 'object'>, ) ), [ ( <class '__main__.MyClsAS'>, ( <class '__main__.MyClsA'>, ) ) ] ]
これだけではgetclasstree関数がどういうフォーマットの戻り値を返すのかわからない。
では、MyClsASのスーパクラスであるMyClsAはどうかというと
例2-MyClsA
classtree=inspect.getclasstree([MyClsA]) print classtree
実行結果
[ ( <type 'object'>, () ), [ ( <class '__main__.MyClsA'>, ( <type 'object'>,) ) ] ]
MyClsAのサブクラスであるMyClsASの更にサブクラスのそのまたサブクラスであるMyClsASSSについても調べてみる。
例3-MyClsASS
classtree=inspect.getclasstree([MyClsASSS]) print classtree
実行結果
[ ( <class '__main__.MyClsASS'>, ( <class '__main__.MyClsAS'>, ) ), [ ( <class '__main__.MyClsASSS'>, ( <class '__main__.MyClsASS'>, ) ) ] ]
ここまで調べてきてなんとなくわかってきた。
どうやら、getclasstree関数は、第1要素にタプル,第2要素にリストの2つの要素を持つリストを返すようだ。
第1要素のタプル内の更に第1要素は、getclasstree関数の引数で指定したクラスのスーパクラスを指している。
すなわち、最初の例(例1)のgetclasstree関数の引数がMyClsASの場合にはMyClsASのスーパクラスであるMyClsAが,
例2のMyClsAの場合にはMyClsAのスーパクラスであるobjectが,
例3のMyClsASSSの場合にはMyClsASSSのスーパクラスであるMyClsASSが格納されている。
そして第1要素のタプル内の第2要素には、更にタプルが入れ子になっていて、第1要素の更にスーパクラスのタプルが格納されている。
第2要素のリストの内部にはこれもタプルが入れ子になっていて、そのタプルの第1要素は、関数の引数に指定されたクラスが、そして2番目の要素には第1要素のスーパクラスのタプルが格納されているようだ。
このように、getclasstree関数はクラスツリーをさかのぼって2つ前までのスーパクラスまでを探してきてくれるがそれ以上前までは探してくれないようだ。
では多重継承の場合はどうだろう。
MyClsAとMyClsBを多重継承したMyClsABSについてみてみよう。
classtree=inspect.getclasstree([MyClsABS]) print classtree
実行結果
[ ( <class '__main__.MyClsA'>, ( <type 'object'>, ) ), [ ( <class '__main__.MyClsABS'>, ( <class '__main__.MyClsA'>, <class '__main__.MyClsB'> ) ) ], ( <class '__main__.MyClsB'>, ( <type 'object'>, ) ), [ ( <class '__main__.MyClsABS'>, ( <class '__main__.MyClsA'>, <class '__main__.MyClsB'> ) ) ] ]
多重継承の場合にはスーパクラスの数×2個の要素を持つリストを返す。
そして、それぞれのスーパクラスに対してタプルとリストの2個づつのペアになるようだ。
参考までに3つのクラスを多重継承した場合は、
class MyClsC(object): pass class MyClsABCS(MyClsA,MyClsB,MyClsC): pass classtree=inspect.getclasstree([MyClsABCS])
実行結果
[ ( <class '__main__.MyClsA'>, ( <type 'object'>, ) ), [ ( <class '__main__.MyClsABCS'>, ( <class '__main__.MyClsA'>, <class '__main__.MyClsB'>, <class '__main__.MyClsC'> ) ) ], ( <class '__main__.MyClsB'>, ( <type 'object'>, ) ), [ ( <class '__main__.MyClsABCS'>, ( <class '__main__.MyClsA'>, <class '__main__.MyClsB'>, <class '__main__.MyClsC'> ) ) ], ( <class '__main__.MyClsC'>, ( <type 'object'>, ) ), [ ( <class '__main__.MyClsABCS'>, ( <class '__main__.MyClsA'>, <class '__main__.MyClsB'>, <class '__main__.MyClsC'> ) ) ] ]
これまでは、1つのクラスだけを引数に指定したが、複数のクラスを指定してやると
classtree=inspect.getclasstree([MyClsASS,MyClsABS]) print classtree
実行結果
[ ( <class '__main__.MyClsA'>, ( <type 'object'>, ) ), [ ( <class '__main__.MyClsABS'>, ( <class '__main__.MyClsA'>, <class '__main__.MyClsB'> ) ) ], ( <class '__main__.MyClsAS'>, ( <class '__main__.MyClsA'>, ) ), [ ( <class '__main__.MyClsASS'>, ( <class '__main__.MyClsAS'>, ) ) ], ( <class '__main__.MyClsB'>, ( <type 'object'>, ) ), [ ( <class '__main__.MyClsABS'>, ( <class '__main__.MyClsA'>, <class '__main__.MyClsB'> ) ) ] ]
MyClsASSとMyClsABSの個々のスーパクラスMyClsASとMyClsAとにMyClsBに対するそれぞれのタプルとリストを要素に持つ、更に複雑怪奇なリストが返される事になる。
ここまで時間をかけてgetclasstree関数の出力をみてきたのだが、果たしてこれが何の役に立つのかというとさっぱりわからない。
苦労して調べた割には得るものがまったく無かった。