【发布时间】:2010-10-23 09:22:18
【问题描述】:
假设我们有一个元类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 下降。所以我尝试将两者都用作元类,但也没有运气。可能是他们对元类有特殊要求,但目前我们似乎处于无证领域。
有什么想法吗?
【问题讨论】:
-
你能解释一下吗?我无法理解您要执行的操作。
标签: python methods metaclass python-descriptors