可作为实例方法调用?

比如说,我们有一个元类。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.MethodTypetypes.UnboundMethodType 没有去任何地方。稍微反省一下,他们似乎是从… … type. 所以我试着把这两个都作为元类使用,但也没有成功。可能是它们作为元类有特殊的需求,但似乎我们现在处于无文档的领域。

有什么想法吗?

解决方案:

只是丰富你 InstanceMethodWrapper 阶级与 __get__ (这完全可以只是 return self)–也就是说,把这个类变成一个 描述符 类型,所以它的实例是描述符对象。 参见 http:/users.cn.comythondownloadDescriptor.htm。 的背景和细节。

另外,如果你是在Python 2.6或更高版本上,可以考虑使用一个类装饰器来代替那个元类–我们添加类装饰器正是因为有太多的元类被用于这种装饰目的,而装饰器的使用确实要简单得多。

给TA打赏
共{{data.count}}人
人已打赏
解决方案

错误:ER_INVALID_JSON_TEXT: Invalid JSON text: Invalid JSON text: ER_INVALID_JSON_TEXT:无效的JSON文本。"无效值。"在列'._data'值的第1位。IN NODE JS

2022-5-12 3:00:22

解决方案

如何在JUnit测试的GET请求中包含路径变量?

2022-5-12 4:00:07

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索