How to add a Decorator to a Class Method

G

gregpinero

How do I add a decorator to a class method? Here's what I want to do,
but I guess my syntax isn't right. Any advice?

class A:
def pre(self,fn):
def new_func(*args,**kwargs):
print 'hi'
fn(*args,**kwargs)
return new_func
@self.pre
def func(self,a,b):
print a+b

Should result in:'hi'
8

Thanks,

-Greg
 
A

Arnaud Delobelle

How do I add a decorator to a class method? Here's what I want to do,
but I guess my syntax isn't right. Any advice?

class A:
def pre(self,fn):
def new_func(*args,**kwargs):
print 'hi'
fn(*args,**kwargs)
return new_func
@self.pre
def func(self,a,b):
print a+b

'self' is not bound during class creation so self.pre does not exist.
Your decorator should be a regular function:

def pre(fn):
...

class A:
@pre
def func(self, x, y):
....

HTH
 
M

Marc 'BlackJack' Rintsch

How do I add a decorator to a class method? Here's what I want to do,
but I guess my syntax isn't right. Any advice?

class A:
def pre(self,fn):
def new_func(*args,**kwargs):
print 'hi'
fn(*args,**kwargs)
return new_func
@self.pre

At this point there is no `self` which is exactly what the exception says
if you run this. This method definition executed at class definition time
so there is no instance of `A`. You can't change it to ``@A.pre`` either
because the class is not fully constructed yet so the class name `A` does
not exist yet. So you have to move `pre()` out of the class.

def pre(fn):
def new_func(*args, **kwargs):
print "'hi'"
fn(*args, **kwargs)
return new_func

class A(object):
@pre
def func(self, a, b):
print a + b

a = A()
a.func(3, 5)

Ciao,
Marc 'BlackJack' Rintsch
 
G

gregpinero

At this point there is no `self` which is exactly what the exception says
if you run this. This method definition executed at class definition time
so there is no instance of `A`. You can't change it to `[email protected]`` either
because the class is not fully constructed yet so the class name `A` does
not exist yet. So you have to move `pre()` out of the class.

def pre(fn):
def new_func(*args, **kwargs):
print "'hi'"
fn(*args, **kwargs)
return new_func

class A(object):
@pre
def func(self, a, b):
print a + b

a = A()
a.func(3, 5)

Ciao,
Marc 'BlackJack' Rintsch


Thanks those answers make sense. But for this function if defined
outside the class:
def pre(fn):
def new_func(*args, **kwargs):
print "'hi'"
fn(*args, **kwargs)
return new_func

Can new_func reference self? Would self just be one of the args?

-Greg
 
L

Laszlo Nagy

Thanks those answers make sense. But for this function if defined
outside the class:



Can new_func reference self? Would self just be one of the args?
Hi,

new_func is a dynamically created function. When pre() is called, it
will return this new function. (This happens when Python tries to excute
the "class A(object)" statement, in other words: it happens during class
definition.) The returned function is unound, and it assigned to A.func.
In other words, the function object is returned by pre(), but is not
called. "new_func" will only be called when you call a.func in your
example. When that happens, Python will find that that object 'a' has no
direct attribute called "func", but there is one in its class "A". So it
will call A.func as a bound method, with its "self" parameter set to the
object that was used to call the method -- namely, "a".

Hope this helps.

Laszlo
 
D

davisn90210

Thanks those answers make sense. But for this function if defined
outside the class:


Can new_func reference self? Would self just be one of the args?

-Greg

For methods, self is always "just one of the args". When the
decorator is applied to a method, self will be args[0] in new_func.

--Nathan Davis
 
L

Laszlo Nagy

Can new_func reference self? Would self just be one of the args?

-Greg

For methods, self is always "just one of the args". When the
decorator is applied to a method, self will be args[0] in new_func.
If you want to use the name "self" instead of args[0] you can:


def pre(fn):
def new_func(self,*args,**kwargs):
print "hi",self
return fn(self,*args,**kwargs)
return new_func



Best,

Laszlo
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,119
Latest member
IrmaNorcro
Top