CallableWrappingMeta
新しいクラスの本体を歩き、そのメソッドをクラスでラップするメタクラスがあるとしましょうInstanceMethodWrapper
:
import types
class CallableWrappingMeta(type):
def __new__(mcls, name, bases, cls_dict):
for k, v in cls_dict.iteritems():
if isinstance(v, types.FunctionType):
cls_dict[k] = InstanceMethodWrapper(v)
return type.__new__(mcls, name, bases, cls_dict)
class InstanceMethodWrapper(object):
def __init__(self, method):
self.method = method
def __call__(self, *args, **kw):
print "InstanceMethodWrapper.__call__( %s, *%r, **%r )" % (self, args, kw)
return self.method(*args, **kw)
class Bar(object):
__metaclass__ = CallableWrappingMeta
def __init__(self):
print 'bar!'
ダミーのラッパーは、引数が入ってくるとそれを出力するだけです。しかし、何か目立つことに気付くでしょう: メソッドはインスタンス オブジェクト レシーバーに渡されInstanceMethodWrapper
ません。クラスの作成中 (メタクラスが処理された後) にインスタンス メソッドに変換されます。
考えられる解決策は、クラスの代わりにデコレータを使用してメソッドをラップすることです。その関数はインスタンス メソッドになります。しかし、実際にInstanceMethodWrapper
は はもっと複雑です。API を提供し、メソッド呼び出しイベントを発行します。クラスはより便利です (そしてパフォーマンスは向上しますが、これはそれほど重要ではありません)。
私もいくつかのデッドエンドを試しました。サブクラスtypes.MethodType
化して、types.UnboundMethodType
どこにも行きませんでした。少し内省すると、彼らはtype
. そのため、両方をメタクラスとして使用してみましたが、どちらもうまくいきませんでした。メタクラスとして特別な要求があるのかもしれませんが、現時点では文書化されていない領域にいるようです。
何か案は?