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.:
[decorator_factory]
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
>thing.
>>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.