假设我们有一个元类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
. 所以我尝试将两者都用作元类,但也没有运气。可能是他们作为元类有特殊要求,但目前我们似乎处于无证领域。
有任何想法吗?