Methods decorated with a decorator class do not have the “self” argument frozen

I have a decorator declared as a class:

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)

... and when I use it to wrap a method in a class, calling that method does not seem to set the instance of the object as the first argument. While this behavior is not exactly unexpected, how would I go about getting self to be frozen when the method becomes an instance method?


Simplified example:

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

Expected instance of foo, instead get an error saying 0 arguments were passed.

5
задан 11 April 2011 в 03:15
поделиться