Reputation: 5875
I'm trying to wrap a function when defining the class, use method in this class's instance
Below is a code that works
class A(object):
def __init__(self):
pass
@self_decorator
def to_be_decorated(self):
pass
def self_decorator(fn):
from functools import wraps
@wraps(fn)
def wrapper(*args, **kwargs):
self = args[0]
return self.app.route('/twip')(fn(*args, **kwargs))
return wrapper
What I actually tries to get:
class A(object):
def __init__(self):
self.app = APP()
@self.app.wrapper_function # which apparently doesn't work
def to_be_decorated(self):
pass
So, is it possible for my way of decorating to work?
Upvotes: 1
Views: 111
Reputation: 365657
A decorator is just a function that gets called at the time of definition.
When you write this:
@self.app.wrapper_function # which apparently doesn't work
def to_be_decorated(self):
pass
it's roughly the same as writing this:
def to_be_decorated(self):
pass
to_be_decorated = self.app.wrapper_function(to_be_decorated)
Once you see it that way, it's obvious why this doesn't work, and couldn't possibly work.
First, A
's class definition doesn't have a self variable, nor does A
have a member app
that could be accessed even if it did. Instead, each instance of A
will have its own unique self.app
.
And even if you wish the interpreter could just "do what I mean", if you think about it, that can't mean anything. You want to call "the" self.app.wrapper_function
method, but there is no such thing. Unless you read through all of the relevant code everywhere the method could be defined or redefined, there's absolutely no guarantee that the self.app.wrapper_function
from different instances of A
will even have the same underlying func_code
. But, even if they did, self.app.wrapper_function
is a bound method—a method bound together with the object it's called on—so they're still all different from each other.
There are plenty of ways around this, but they're all going to be the same trick: Use some kind of indirection to get a function which isn't a member of self.app
or self
, and references self.app
at call time. This is basically what your self_decorator
does, and it's unavoidable.
Upvotes: 0
Reputation: 33397
At the class definition there's no self as the class do not exists yet and cannot be instantiated.
You can use
class A(object):
app = APP()
@app.wrapper_function
def to_be_decorated(self):
pass
But that would be a class variable.
Upvotes: 2