2011-04-11 85 views
5

我必须声明为类装饰:方法饰以装饰类没有“自我”的说法冷冻

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


简单的例子:FOO的

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() 

预计实例,而不是得到一个错误说0参数传递。

+0

+1对于“简单示例”:) – 2011-04-11 03:21:53

+0

我猜这是因为'some_method'不再是函数,而是'test_decorator'类的对象 - 实例 - 所以它不会创建绑定方法。我不知道如何使该场景与“装饰类”工作虽然.. – 2011-04-11 03:26:18

回答

4

想通了 - 需要的,以便建立一个MethodType像这样结合以限定__get__方法:

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

调用该冻结self参数的物体上的方法时,其创建一个MethodType对象。

+0

[This](http://stackoverflow.com/questions/5469956/python-decorator-self-is-mixed-up)发表会谈关于描述符协议 – Pakman 2012-05-25 20:12:02