jordan_bethの日記: python getattr で取得したメソッドの呼び出し 1
日記 by
jordan_beth
インスタンスのメソッドを動的に呼び出す必要があったので、getattr で取得し、そこメソッドを実行するコードを書いていてハマる。
class Test(object) :
def __init__(self, multiplier) :
self.multiplier = multiplier
def calc(self, a, b) :
print(self.multiplier * (a + b))
というクラスがあったとして、
>>> var = Test(10)
>>> func = getattr(var, 'calc')
>>> func(var, 2, 4)
Traceback (most recent call last):
File "", line 1, in
TypeError: calc() takes exactly 3 arguments (4 given)
で引数が多いと怒られる。
>>> func(2, 4)
60
ということで、インスタンスで getattr したメソッドでは、その呼出においてインスタンスオブジェクトの引き渡しは必要ないようだ。バインド済みだからってこと?
関数の種類 (スコア:0)
メソッドは操作対象を属性として持っているのでインスタンスから得たメソッドは束縛しなおす必要がありません。
@staticmethodを使って定義したメソッドは普通の関数と同じです。
メソッドが持っている操作対象のインスタンスはmethod.__self__で取得できます。
>>> class C:
... def a(self): pass
... @staticmethod
... def b(): pass
...
>>> C.a
<unbound method C.a>
>>> C.b
<function b at 0x00DA5EF0>
>>> c = C()
>>> c.a
<bound method C.a of <__main__.C instance at 0x00DAC508>>
>>> c.b
<function b at 0x00DA5EF0>
>>> c.a.__self__ is c
True
なおmethod.__self__は読み取り専用なので後で束縛を変更したい場合はmethod.__func__で束縛される前の関数(未束縛のメソッドではない)が取得できます。
普通の関数をメソッドにするにはnew.instancemethod関数を使います。
詳しくは言語リファレンスの3.2.標準型の階層の呼び出し可能型の項を参照して下さい。