クラスがあるとしましょう
class Foo:
def __init__(self):
pass
def meth1(self, *args):
do_stuff()
def meth2(self, **kwargs):
more_stuff()
def callme(self):
print "I'm called!"
を実行しcallme()
た後に呼び出されるようにスマートに変更したいと思います。それ、どうやったら出来るの?私はクラス デコレータもメタクラスも使用したことがないので、どちらが正しい方法なのか、またそれらを適切に使用する方法がわかりません。meth1
meth2
メタクラスを使用して、次のことをまとめました。
from types import FunctionType
def addcall_meta(name, bases, dct):
newdct = dict(dct)
for k, v in dct.items():
if isinstance(v, FunctionType) and k not in ('__metaclass__', 'callme'):
# the above can include more filters such as not startswith, etc.
print k, 'is a function!'
def newmethod(self, *args, **kwargs):
v(self, *args, **kwargs)
dct['callme'](self)
newdct[k] = newmethod
return type(name, bases, newdct)
クラス デコレータを使用する場合:
def addcall_deco(cls):
dct = {}
for k, v in cls.__dict__.items():
if isinstance(v, FunctionType) and k != 'callme':
def newv(self, *args, **kwargs):
v(self, *args, **kwargs)
self.callme()
cls.k = newv
return cls
どちらも私の非常に単純な例ではうまくいくようです:
In [75]: Foo()
I'm called!
Out[75]: <__main__.Foo instance at 0x21ed680>
一方を使用し、他方を使用しない明らかな理由はありますか (特定のコーナー ケースなど)。また、何とか使用できると思い__new__
ますが、常識的な観点から、すべてのインスタンスではなく、クラスを変更したいと考えています。