473,396 Members | 1,832 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

How to add a Decorator to a Class Method

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:
>>a = A()
a.func(3,5)
'hi'
8

Thanks,

-Greg
Nov 20 '07 #1
6 1865
On Nov 20, 4:59 am, "gregpin...@gmail.com" <gregpin...@gmail.com>
wrote:
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

--
Arnaud

Nov 20 '07 #2
On Mon, 19 Nov 2007 20:59:51 -0800, gr********@gmail.com wrote:
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
Nov 20 '07 #3
On Nov 20, 2:05 am, Marc 'BlackJack' Rintsch <bj_...@gmx.netwrote:
On Mon, 19 Nov 2007 20:59:51 -0800, gregpin...@gmail.com wrote:
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

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
Nov 20 '07 #4
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?
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

Nov 20 '07 #5
On Nov 20, 12:32 pm, "gregpin...@gmail.com" <gregpin...@gmail.com>
wrote:
On Nov 20, 2:05 am, Marc 'BlackJack' Rintsch <bj_...@gmx.netwrote:
On Mon, 19 Nov 2007 20:59:51 -0800, gregpin...@gmail.com wrote:
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

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
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
Nov 20 '07 #6
>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

Nov 20 '07 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

22
by: Ron_Adam | last post by:
Hi, Thanks again for all the helping me understand the details of decorators. I put together a class to create decorators that could make them a lot easier to use. It still has a few glitches...
3
by: Ron_Adam | last post by:
Ok... it's works! :) So what do you think? Look at the last stacked example, it process the preprocess's first in forward order, then does the postprocess's in reverse order. Which might be...
2
by: lcaamano | last post by:
We have a tracing decorator that automatically logs enter/exits to/from functions and methods and it also figures out by itself the function call arguments values and the class or module the...
5
by: Doug | last post by:
I am looking at using the decorator pattern to create a rudimentary stored proc generator but am unsure about something. For each class that identifies a part of the stored proc, what if I want to...
11
by: glen.coates.bigworld | last post by:
I'm developing a library at the moment that involves many classes, some of which have "exposed" capabilities. I'm trying to design a nice interface for both exposing those capabilities, and...
3
by: Gregory | last post by:
I recently reviewed the decorator pattern in the GOF book and noticed a problem. Let look at the example given in the book. For simplicity I removed intermediate Decorator class. // Interface...
9
by: Raymond Hettinger | last post by:
I had an idea but no time to think it through. Perhaps the under-under name mangling trick can be replaced (in Py3.0) with a suitably designed decorator. Your challenge is to write the decorator....
9
by: Christian Hackl | last post by:
Hi! I've got a design question related to the combination of the NVI idiom (non-virtual interfaces, ) and popular object-oriented patterns such as Proxy or Decorator, i.e. those which have the...
4
by: thomas.karolski | last post by:
Hi, I would like to create a Decorator metaclass, which automatically turns a class which inherits from the "Decorator" type into a decorator. A decorator in this case, is simply a class which...
5
by: Lee Harr | last post by:
I have a class with certain methods from which I want to select one at random, with weighting. The way I have done it is this .... import random def weight(value):
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.