[Python-Dev] PEP 318: How I would implement decorators

Phillip J. Eby pje at telecommunity.com
Tue Apr 6 19:32:53 EDT 2004

At 03:09 PM 4/6/04 -0700, Jim Hugunin wrote:

>1. Use a "decorate" method instead of a call to avoid the worst problems
>like [returns].

Mike Pall actually suggested this recently, although he called the method 
'__decorate__' and proposed that it use a type slot.

>   This has the added benefit in my eyes of making it a little
>harder to write small decorators and thus encouraging people to think a
>little more before writing these meta-programs.

Actually, it's pretty trivial to write a 'decorator_factory' decorator that 
you could then use to make it easy again, i.e.:

def returns(typ):

So, the approach won't actually discourage people from writing small 
decorators.  :)

>3. Provide a clear set of guidelines for good decorators, i.e.
>   a. decorators should not have side effects outside of the class/function

This is a use case that people have explicitly requested.  IIRC, there have 
been much better examples than 'atexit' that have been posted here.

>   b. decorators should return the same kind of thing they are given

I think it's probably more appropriate to say that decorators should verify 
that their input is something useful to them, and return a helpful error 
message if not.

>+ sys._getframe()
>There should be a consensus on whether or not decorators like 'generic' are
>a good or a bad idea.  If they're a good idea then the decorate method
>should get an extra argument exposing the local namespace so that
>sys._getframe() won't be required.  I'd be in favor of adding that argument
>to decorate.

I'm +1 on adding the argument, if there's a decoration method, be it 
'decorate' or '__decorate__'.  As long as decorators are plain functions, 
though, I think the extra argument makes interoperability harder.  By the 
way, it's not clear whether decorators in the general case might not also 
require the active globals, in addition to the active locals.

>+ classmethod and staticmethod
>These two decorators are a big problem because they don't return the same
>kind of thing as they are given.  This means they always have to be the last
>decorator applied in any list.  That kind of restriction is never a good
>Personally, I'd like to see these changed from returning a new object to
>instead setting an attribute on the existing function/method object.  Then
>the method object could use this attribute to implement its __get__ method
>correctly.  This would make these decorators compose very nicely with all of
>the other decorators; however, it would be a fairly major change to how
>Python handles static and class methods and I'm doubtful that would fly.

This issue will apply to any decorator that creates a descriptor, so 
kludging functions for this aren't going to help any other kinds of 
descriptor-making decorators.  But, descriptors (other than functions) 
aren't usually callable, so as long as decorators that expect callables 
check for callability, I don't think this is too big of a deal.

More information about the Python-Dev mailing list