Pythonのクラスの挙動を調べる:class構文の外からクラスにメンバ関数を追加(1)
Pythonのクラスの挙動を調べる:class構文の外からクラスにメンバ関数を追加(1)
Pythonでプラグイン的な機構を実装する際、あるモジュールで定義されたクラスに対し、ほかのモジュールからメンバ関数を追加できると楽しいのでは?とふと思う。
ちょっと分かりにくいが、例えばHogeというクラスがhoge.pyで定義されており、Hogeクラスのメンバ関数を追加するコードがplugin.pyで定義されている。そして、plugin.pyで定義されている機能を使いたい場合のみimport pluginすると、その機能がHogeクラスで利用できるようになる、というイメージだ。
ということで、ちょっと試してみた。
[Macintosh:~]$ python Python 2.5.1 (r251:54863, Feb 6 2009, 19:02:12) [GCC 4.0.1 (Apple Inc. build 5465)] on darwin Type "help", "copyright", "credits" or "license" for more information. # 適当な関数を定義 >>> class FooBar(object): ... def func1(self): ... print "func1!" ... def func2(self): ... print "func2!" ... # FooBarクラスのインスタンスを作成 >>> a = FooBar() >>> a.func1() func1! >>> a.func2() func2! # FooBarは__main___内にクラスオブジェクトして記録される >>> locals() {'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__doc__': None, 'a': <__main__.FooBar object at 0x2454f0>, 'FooBar': <class '__main__.FooBar'>} >>> print FooBar <class '__main__.FooBar'> >>> print FooBar.__dict__ {'func2': <function func2 at 0x5e2f0>, '__module__': '__main__', 'func1': <function func1 at 0x5e2b0>, '__dict__': <attribute '__dict__' of 'FooBar' objects>, '__weakref__': <attribute '__weakref__' of 'FooBar' objects>, '__doc__': None} # FooBarクラスに追加する関数を定義 >>> def add1(self): ... print "add1!" ... # add1関数をFooBarクラスのメンバに追加 >>> FooBar.add1 = add1 # クラスを改変する前に作成したインスタンスも影響を受ける! >>> a.add1() add1! >>> print FooBar.__dict__ {'func2': <function func2 at 0x5e2f0>, '__module__': '__main__', 'add1': <function add1 at 0x5e270>, 'func1': <function func1 at 0x5e2b0>, '__dict__': <attribute '__dict__' of 'FooBar' objects>, '__weakref__': <attribute '__weakref__' of 'FooBar' objects>, '__doc__': None} >>>
ということで、少なくともクラスオブジェクトに対して属性を追加することで、クラスにメンバ関数を追加できることは分かりました。なるほどなるほど。