decorators ?

P

Paul McGuire

km said:
Hi all,
was going thru the new features introduced into python2.4 version.
i was stuck with 'decorators' - can someone explain me the need of such a thing called decorators ?
tia
KM

Here are some example on the Python Wiki:
http://www.python.org/moin/PythonDecoratorLibrary

I think memoize is my favorite so far.

I'm not sure if the example behavior is all that clear. For a given set of
arguments, the Memoize class keeps a dictionary of input arg values and
return values. In subsequent calls, sets of args are looked up in the
dictionary of previous calls - if the arg list is found, then the function
is bypassed, and the cached return value is returned immediately. This can
greatly speed up calls to functions that are very time-consuming, or
recursive. This is why the Wiki page lists factorial() and fibonacci()
examples. Of course, Memoize assumes that the return value is purely a
function of the input args, and not subject to any external state.

Of course, one could readily implement this behavior within the target
functions. The beauty of the decorator is that this optimization is done
*completely* outside the function itself, so the function remains fairly
pure at the application level, and does not get cluttered with variables
like "resultsCache" and so on. Also, in the interests of maximizing reuse
and avoiding the bug-proneness of cut-and-paste, isolating Memoize into a
reusable decorator helps avoid introducing bugs (vs. hard-coding this
optimization into successive functions - did you remember to initialize the
dictionary?), and leverages any optimizations or bug-fixes.

(I focused on Memoize, but these comments apply to any of the decorators on
this wiki page.)

-- Paul
 
?

=?ISO-8859-1?Q?BJ=F6rn_Lindqvist?=

Some more decorator examples.

How to create abstract methods using an @absractmethod decorator:
http://www.brpreiss.com/books/opus7/html/page117.html

Generics, property getters and setters. I don't know what these
decorators are supposed to do:
http://www.cis.upenn.edu/~edloper/pydecorators.html -

And according to this,
http://www.prothon.org/pipermail/prothon-user/2004-August/003173.html,
one use of decorators is to put a functions docstring before the def
f(): line like this:

@doc("""blabla does something.""")
def blabla():

Here is one decorator for optimizing:
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/277940

I think the essence of decorators is that it makes it possible to do
in Python what you in other languages do with method qualifiers. This
declaration in Java

public synchronized static void doStuff()

would you write in Python as

@public
@synchronized
@staticmethod
def doStuff():

I haven't seen an example of a @synchronized decorator, but I assume
it is possible. Hopefully, it is possible to create a @private
decorator which throws some kind of exception when a private method is
accessed from outside the class. If that is possible, then it would
also be nice to have a @public decorator which doesn't do anything. As
far as I know, only two decorators are included in the standard
library in Python 2.4, @staticmethod and @classmethod. That is a
little unfortunate, because many more "obvious ones" could have been
included. The devs are probably planning to correct that in the coming
versions.
That is all I know about decorators. Or rather THINK I know from
reading stuff on the internet. Please don't flame me if I'm wrong. :)
 
J

Jacek Generowicz

BJörn Lindqvist said:
I think the essence of decorators is that it makes it possible to do
in Python what you in other languages do with method qualifiers.

I find it fascinating that the addition of a bit of syntax sugar gives
the perception that a whole range of new and previously unthinkable
possibilities have opened themselves before us.

@X
def Y...
...


is merely syntax sugar (or syntax ammonia, for some) for


def Y...
...
Y = X(Y)

Anything you can do with decorators, you could do before (with the
exception of rebinding the __name__ of functions).

And yet, that bit of syntax sugar really _does_ make a big difference
to the lengths that people are prepared to take the possibilities that
the underlying feature affords them.
 
S

Skip Montanaro

Jacek> Anything you can do with decorators, you could do before (with
Jacek> the exception of rebinding the __name__ of functions).

And while that feature was added because we realized it would be nice if the
decorated function could have the same name as the original function, it
seems like that change could stand on its own merits.

Skip
 
K

km

Hi all,
was going thru the new features introduced into python2.4 version.
i was stuck with 'decorators' - can someone explain me the need of such a thing called decorators ?
tia
KM
 
M

Michael Hudson

Skip Montanaro said:
Jacek> Anything you can do with decorators, you could do before (with
Jacek> the exception of rebinding the __name__ of functions).

And while that feature was added because we realized it would be nice if the
decorated function could have the same name as the original function, it
seems like that change could stand on its own merits.

Indeed. I'd been meaning to do it for at least a year...

Cheers,
mwh
 
J

Josiah Carlson

Jacek Generowicz said:
I find it fascinating that the addition of a bit of syntax sugar gives
the perception that a whole range of new and previously unthinkable
possibilities have opened themselves before us.

@X
def Y...
...


is merely syntax sugar (or syntax ammonia, for some) for


def Y...
...
Y = X(Y)

Anything you can do with decorators, you could do before (with the
exception of rebinding the __name__ of functions).

And yet, that bit of syntax sugar really _does_ make a big difference
to the lengths that people are prepared to take the possibilities that
the underlying feature affords them.


Technically, everything can be performed in assembly. The point of
syntactic sugar (or ammonia) is to make things less painful. While
everything was possible before, adding the decorators /after/ defining
the function hid the decorators, and was susceptible to mistyping.

I previously posted about Philip Eby's use of decorators in PyObjC. In
his case, it saved him from typing 40-character function names 3
times.

- Josiah
 
D

Daniel 'Dang' Griffith

Here are some example on the Python Wiki:
http://www.python.org/moin/PythonDecoratorLibrary

I think memoize is my favorite so far.

Memoize is certainly a readily approachable example.

But the factorial example on the wiki has a defect. It incorrectly
calculates factorial(0) as 0, when it should be 1. I don't know how
to edit the "inline" code in the wiki, but if someone out there knows
how, consider changing:

if n < 2:
return n

to:

if n < 2:
return 1

Have a nice day!
--dang
 
T

Terry Reedy

Daniel 'Dang' Griffith said:
But the factorial example on the wiki has a defect. It incorrectly
calculates factorial(0) as 0, when it should be 1.

This is a matter of definition, and definitions apparently differ. fact(0)
== 0 is a backward projection from the definition f(1) = f(2) = 1 in
1-based systems, which is the context for the rabbit problem in which the
first year is year 1, not year 0. Disagreement is not defect.

Terry J. Reedy
 
T

Tim Peters

[Daniel 'Dang' Griffith]
[Terry Reedy]
This is a matter of definition, and definitions apparently differ.
fact(0) == 0 is a backward projection from the definition f(1) = f(2)
= 1 in 1-based systems, which is the context for the rabbit
problem in which the first year is year 1, not year 0.
Disagreement is not defect.

Terry, since you're talking about "the rabbit problem", are you sure
you're talking about the factorial example? It sounds like you're
talking about the Fibonacci example. I agree with Daniel about the
factorial function: there's no disagreement about 0!=1, 1!=1, 2!=2,
3!=6, 4!=24, ..., that I've ever seen. The first two terms in a
Fibonacci sequence are indeed arbitrary, though.
 
F

Fernando Perez

Terry said:
This is a matter of definition, and definitions apparently differ. fact(0)
== 0 is a backward projection from the definition f(1) = f(2) = 1 in
1-based systems, which is the context for the rabbit problem in which the
first year is year 1, not year 0. Disagreement is not defect.

No, fact(0)==1 simply because any proper definition of a factorial has to match
up with the gamma function (offset by one) at all non-negative integers. So
there's no room for any ambiguity here.

Regards,

f
 
F

Fernando Perez

Fernando said:
No, fact(0)==1 simply because any proper definition of a factorial has to
match
up with the gamma function (offset by one) at all non-negative integers. So
there's no room for any ambiguity here.

I should have added a link to the ever-useful mathworld:

http://mathworld.wolfram.com/Factorial.html

This has as much detail about n! and Gamma(z) as you'll ever want to know :)

Cheers,

f
 
T

Terry Reedy

Tim Peters said:
Terry, since you're talking about "the rabbit problem", are you sure
you're talking about the factorial example? It sounds like you're
talking about the Fibonacci example.

Of course. 0! is 1 multiplied by nothing (not 0) which is 1, just as n**0
is 1 multiplied by n 0 times and hence 1.

TJR
 

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

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,196
Latest member
ScottChare

Latest Threads

Top