015:特異メソッド
PythonにはRubyのような「特異メソッドのための構文」はありません。 しかし、new.instancemethod モジュールを使えば、特異メソッドを実現できます。
import new
class A(object):
def __init__(self, n):
self.n = n
def spam(self, x):
return self.n*x + 2
a1 = A(3)
a1.spam = new.instancemethod(spam, a1, A)
print a1.spam # => <bound method A.spam of <__main__.A object at 0x00B014D0>>
print a1.spam(3) # => 11
a2 = A(3)
print a2.spam(3) # AttributeErrorが発生
ちなみにRubyのように文字列や整数にまで特異メソッドを追加する事は出来ません、悪しからず。
ところで、一々
foo.bar = new.instancemethod(bar, foo, Klass)
と書くのは面倒です。 しかし、関数デコレータを使うと、短く出来ます。
#singletonmethod.py
import new
def singletonmethod(obj):
def f(function):
m = new.instancemethod(function, obj, type(obj))
setattr(obj, function.__name__, m)
return function
return f
これをsingletonmethod.pyに書き込み、Pythonのパスが通った場所(C:Python26Libsite-packages等)に保存します。
以下の様に使います。
from singletonmethod import singletonmethod
class A(object):pass
a1 = A(3)
@singletonmethod(a)
def spam(self, x):
return 3*x + 2
print a1.spam # => <bound method A.spam of <__main__.A object at 0x00B014D0>>
print a1.spam(3) # => 11