execによるmixin

以前の自分の日記(2008/2/21、2008/2/22)でimportによるmixinの方法を書いたが、『まるごとRuby!』のartonさんの記事を見て、execにより実現できることに気がついた。文字列を動的に作っても良いので結構応用範囲は広いと思う。k.inabaさんの『わなD』に似たような記事があったような気がする。

In [1]: s='''
   ...: def foo(self):
   ...:     print 'foo'
   ...:
   ...: def bar(self, o):
   ...:     print o
   ...: '''

In [2]: class Foo(object):
   ...:     exec(s)
   ...:

In [3]: Foo.foo
Out[3]: <unbound method Foo.foo>

In [4]: f = Foo()

In [5]: f.foo()
foo

In [6]: f.bar('aaa')
aaa

In [7]: f.bar(Foo)
<class '__main__.Foo'>

他に検索して以下のものを見つけた。

前者のポイントは、以下のように継承関係を動的に更新している。

def MixIn(pyClass, mixInClass):
    pyClass.__bases__ += mixInClass

後者は単に属性をコピーしているだけ。