The Artima Developer Community
Sponsored Link

Weblogs Forum
Decorators I: Introduction to Python Decorators

34 replies on 3 pages. Most recent reply: Sep 11, 2014 6:32 PM by Gary Mason

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 34 replies on 3 pages [ « | 1 2 3 | » ]
Evan Cofsky

Posts: 9
Nickname: theunixman
Registered: Jun, 2006

Python Compile-Time Posted: Oct 22, 2008 4:51 PM
Reply to this message Reply
Advertisement
Python has extremely late type binding. It's compilation pass builds a stream of byte-codes that run on the Python virtual machine, but does nothing at all about type information, tagging variables with specific types, or binding function signatures to names. In fact, variables never have types, only the instances they refer to at run-time.

But at run-time, Python does have an early pass it makes for each module, and this is where the decorators get run, classes are defined, and any other module-level code executed. The decorators modify their functions here, at least for functions defined during this phase. But at any point during the life of the virtual machine, new functions can be created, new modules loaded, and thus decorators applied to new functions.

John P. Speno

Posts: 93
Nickname: avocado
Registered: Jan, 2004

Re: Decorators I: Introduction to Python Decorators Posted: Oct 25, 2008 10:50 AM
Reply to this message Reply
Thanks for working on this project. :-)

If I'm a newbie wanting to learn python decorators, I don't want to read several introductory paragraphs about things that aren't what I'm here to learn. Therefore, I would suggest you remove these sections or relate them to after the lesson.

Decorators vs. the Decorator Pattern
History of Macros
The Goal of Macros

Also, I'd avoid the talk about AOP too. Just get to the how to and why to parts right away.

Bruce Eckel

Posts: 875
Nickname: beckel
Registered: Jun, 2003

Re: Decorators I: Introduction to Python Decorators Posted: Oct 25, 2008 2:39 PM
Reply to this message Reply
Thanks for the suggestion. Those parts might be moved to the back of the chapter at some point (I usually have to ruminate on these suggestions, so it probably won't appear right away).

However, this will not be an intro to the language like Thinking in C++ and Thinking in Java -- there are plenty of good intro books on Python. This book will focus on more intermediate and advanced level stuff. Although there is a "quick python for programmers" intro at the beginning we will assume the reader will be able to learn more of the basics elsewhere.

Guido van van Rossum

Posts: 359
Nickname: guido
Registered: Apr, 2003

Re: Decorators I: Introduction to Python Decorators Posted: Oct 26, 2008 2:14 PM
Reply to this message Reply
I'm curious -- why do you find using a class to define a decorator easier to understand than the more traditional nested function pattern? Is it because you're not comfortable with lexically scoped nested functions (or because you worry that your audience isn't)?

John Zabroski

Posts: 272
Nickname: zbo
Registered: Jan, 2007

Re: Decorators I: Introduction to Python Decorators Posted: Oct 26, 2008 2:49 PM
Reply to this message Reply
Indeed, you can use Python decorators to implement the Decorator pattern, but that's an extremely limited use of it.

It sounds like you are artificially assigning a narrow set of use cases to the Decorator pattern. The most important implementation aspect of this pattern, in my humble opinion, is obedience to the Open-Closed Principle.


@Decorators allow you to inject or modify code in functions or classes. Sounds a bit like Aspect-Oriented Programming (AOP) in Java, doesn't it? Except that it's both much simpler and (as a result) much more powerful.

Are you referring to Java annotations, or to a specific implementation of AOP for Java, such as AspectJ?

Aspects allow you to preserve the Open-Closed Principle by reconsidering what is considered a component.

Also, something I've always wondered but never had enough Python experience to know: What are the pitfalls? See for instance: http://ieeexplore.ieee.org/search/wrapper.jsp?arnumber=4291035

John Zabroski

Posts: 272
Nickname: zbo
Registered: Jan, 2007

Re: Decorators I: Introduction to Python Decorators Posted: Oct 26, 2008 2:54 PM
Reply to this message Reply
@ Is it because you're not comfortable with lexically scoped nested functions (or because you worry that your audience isn't)?

Well, for a somewhat advanced book, this worry seems silly?

Bruce Eckel

Posts: 875
Nickname: beckel
Registered: Jun, 2003

Re: Decorators I: Introduction to Python Decorators Posted: Oct 27, 2008 11:02 AM
Reply to this message Reply
> I'm curious -- why do you find using a class to define a
> decorator easier to understand than the more traditional
> nested function pattern? Is it because you're not
> comfortable with lexically scoped nested functions (or
> because you worry that your audience isn't)?

The multiple levels of function definitions were always a stumbling block for me when trying to understand decorators. The two-step process of the class was when I got the "aha" about it. Once you get it, then it was much easier for me to understand the nested functions.

Bruce Eckel

Posts: 875
Nickname: beckel
Registered: Jun, 2003

Re: Decorators I: Introduction to Python Decorators Posted: Oct 27, 2008 11:11 AM
Reply to this message Reply
> Well, for a somewhat advanced book, this worry seems silly?

The "somewhat" modifier is very important here. In an intro book you are forced to describe everything in lock step, never mentioning anything before it has been thoroughly introduced. That difficult constraint is removed.

In addition, we can talk about anything in this book, whereas in an intro book you are limited.

That said, people will still be coming to a topic without knowing about it and it will need to be introduced, as much as possible, as if they have never seen it before.

David Goodger

Posts: 48
Nickname: goodger
Registered: Apr, 2004

Re: Decorators I: Introduction to Python Decorators Posted: Oct 29, 2008 10:40 AM
Reply to this message Reply
Since this article is intended for "Python 3 Patterns & Idioms", wouldn't it be a good idea to write the code using Python 3 syntax? What shouts Python 2 to me is your use of "print" as a statement; in Python 3 it's "print(x)" (a function) instead of "print x". There may be other cases as well, but I'm not familiar enough with Python 3 yet :-)

My suggestion: write and test your code with Python 3.

Bruce Eckel

Posts: 875
Nickname: beckel
Registered: Jun, 2003

Re: Decorators I: Introduction to Python Decorators Posted: Oct 29, 2008 2:08 PM
Reply to this message Reply
> Since this article is intended for "Python 3 Patterns &
> Idioms", wouldn't it be a good idea to write the code
> using Python 3 syntax? What shouts Python 2 to me is your
> use of "print" as a statement; in Python 3 it's "print(x)"
> (a function) instead of "print x". There may be other
> cases as well, but I'm not familiar enough with Python 3
> yet :-)
>
> My suggestion: write and test your code with Python 3.

It's evolutionary. Much of the current version of the book is still just roughly cut from a Java version, and I'm still absorbing Python 3 stuff. I expect a lot of changes once I put up the initial draft of the book, when people can start pulling it down using Bazaar and changing it. Right now I'm just trying to get the basic structure in place so most of those questions are answered.

Also, I had hoped for a final version of Python 3 to be out by now but there appears to be some delays. In addition, it looks like more features made it back into Python 2.6 than were originally expected, so a lot of tests can be done with 2.6.

Finally, I think that the majority of people are still using 2.x so the weblog postings here will be more useful to them.

John Posner

Posts: 1
Nickname: jjposner
Registered: Mar, 2009

Re: Decorators I: Introduction to Python Decorators Posted: Mar 6, 2009 2:31 PM
Reply to this message Reply
Consider this:


@mydecorator
def myfunc(a,b,c):
...


* If "mydecorator" names a function, then the FUNCTION ITSELF is applied to myfunc.

* But if "mydecorator" names a class, then AN INSTANCE OF THE CLASS is applied to myfunc, not the CLASS ITSELF.

Is that an inconsistency?

Greg Turnquist

Posts: 1
Nickname: gregturn
Registered: Mar, 2009

Re: Decorators I: Introduction to Python Decorators Posted: Mar 16, 2009 1:31 PM
Reply to this message Reply
This tactic of using decorators DOES require you to edit code directly. In some cases, this is perfectly fine, and would allow you to nicely define AOP behaviors. But at other times, you want to apply the advice from another place, without editing the code. Spring Python (http://springpython.webfactional.com) has a module that supports this. I have also found decorators very useful, and have built an IoC container using decorators, as well as the ability to mark-up transactions with an @transactional decorator.

Matthew H

Posts: 2
Nickname: syllogism
Registered: Jul, 2009

Re: Decorators I: Introduction to Python Decorators Posted: Jul 11, 2009 10:35 AM
Reply to this message Reply
I needed to add an LRU cache to a class method, so I started learning about decorators and found these posts useful. But I think I've hit a limitation of using a class and __call__.

When the class is used to wrap a class method, I can't see how to get access to the instance variable, "self":

def __call__(self, *args):
hashable = []
key = self._hash(args)
try:
value = self.cache[key]
print "Used cache"
self.hist.remove(key)
except KeyError:
print "Baking fresh"
value = self.f(*args)
self.cache[key] = value
if len(hist) == self.n:
lru = self.hist.pop(-1)
self.cache.pop(lru)
self.hist.insert(0, key)
return value
[code]

The problematic part is where the arguments aren't memoized and I need to "bake fresh" --- I can't pass self back to the method.

I'd prefer to use a class than a wrapped function, because it seems like a more natural way to preserve the cache and history states. Is there anything I can do?

Matthew H

Posts: 2
Nickname: syllogism
Registered: Jul, 2009

Re: Decorators I: Introduction to Python Decorators Posted: Jul 11, 2009 10:39 AM
Reply to this message Reply
Bother, that'll teach me not to preview. Apologies.


def __call__(self, *args):
hashable = []
key = self._hash(args)
try:
value = self._cache[key]
print "Used cache"
self._hist.remove(key)
except KeyError:
print "Baking fresh"
value = self.f(*args)
self._cache[key] = value
if len(self._hist) == self.n:
lru = self._hist.pop(-1)
self._cache.pop(lru)
self._hist.insert(0, key)
return value

Alex Walker

Posts: 1
Nickname: raindogs
Registered: Mar, 2010

Re: Decorators I: Introduction to Python Decorators Posted: Mar 5, 2010 1:46 PM
Reply to this message Reply
Thank you very much for this clear and informative article. I've just started looking at Python decorators and this was a very helpful introduction.

Flat View: This topic has 34 replies on 3 pages [ « | 1  2  3 | » ]
Topic: A Hazard of Covariant Return Types and Bridge Methods Previous Topic   Next Topic Topic: For the Sake of Simplicity


Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2014 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use - Advertise with Us