用decorator类装饰的方法没有冻结“self”参数

时间:2011-04-11 03:07:22

标签: python decorator

我有一个装饰器声明为一个类:

class predicated(object):
    def __init__(self, fn):
        self.fn = fn
        self.fpred = lambda *args, **kwargs: True

    def predicate(self, predicate):
        self.fpred = predicate
        return self

    def validate(self, *args, **kwargs):
        return self.fpred(*args, **kwargs)

    def __call__(self, *args, **kwargs):
        if not self.validate(*args, **kwargs):
            raise PredicateNotMatchedError("predicate was not matched")
        return self.fn(*args, **kwargs)

...当我用它来包装类中的方法时,调用该方法似乎并没有将对象的实例设置为第一个参数。虽然这种行为并非完全出乎意料,但当方法成为实例方法时,如何让self被冻结?


简化示例:

class test_decorator(object):
    def __init__(self, fn):
        self.fn = fn
    def __call__(self, *args, **kwargs):
        return self.fn(*args, **kwargs)

class Foo(object):
    @test_decorator
    def some_method(self):
        print(self)

Foo().some_method()

foo的预期实例,而是获得一个错误,表示传递了0个参数。

1 个答案:

答案 0 :(得分:4)

想出来 - 需要定义__get__方法,以便像这样创建MethodType绑定:

def __get__(self, obj, objtype=None):
    return MethodType(self, obj, objtype)

在对冻结MethodType参数的对象调用方法时创建self对象。

相关问题