特異メソッドの定義

メタプログラミングrubyの内容をpythonでやってみようと思い試行錯誤していた途中で発見。
types.MethodTypeに渡すと関数がメソッドに変化するらしい。

特異メソッドの定義

#define eigen method examples

class A():
    def __init__(self, x):
        self.x = x

    def f(self):
        return self.x

import types
def g(self):
    return self.x * self.x

a = A(10)
print a.f() # => 10
a.g = types.MethodType(g, a, A)
print a.g() # => 100

aa = A(10)
# print aa.g() # => AttributeError

__init__の中で定義するとインスタンスメソッドを動的に定義できる。

class A():
    def __init__(self, x):
        self.x = x
        if getattr(self, "h", None) is None:
            def h(self):
                return "fooo"
            self.h = types.MethodType(h, self, A)

    def f(self):
        return self.x

    def run(self, *args):
        print "%s:" % self
        for f in args:
            fun = getattr(self, f, None)
            if fun is not None: print "\t%s:%s" % (f,fun())
            else: print "\t%s: not-found --" % f
                
import types
def g(self):
    return self.x * self.x

a = A(10)
a.g = types.MethodType(g, a, A)
a.run("f", "g", "h")
aa = A(10)
aa.run("f", "g", "h")

output

<__main__.A instance at 0x7f52516812d8>:
	f:10
	g:100
	h:fooo
<__main__.A instance at 0x7f5251681320>:
	f:10
	g: not-found --
	h:fooo