[Python-Dev] PEP 318: Decorators last before colon

Jewett, Jim J jim.jewett at eds.com
Tue Mar 30 11:34:38 EST 2004


Ka-Ping Yee:

> Three different positions for decorators have been suggested:

>    (a) def [decorator] func(arg, arg):
>    (b) def func [decorator] (arg, arg):
>    (c) def func(arg, arg) [decorator]:

You forgot before and after

	using:
	    classmethod
	def func(arg1, arg2):
	    pass

	def func(arg1, arg2):
	    .classmethod
	    pass

There is also a possibility of two separate places, 
depending on whether the original object is 

(1)  returned, possibly with extra attributes, or
(2)  replaced with a new entry point (which might or 
might not forward to the original, change the signature 
entirely, do something completely different).

	using:
	    classmethod
	def func(arg1, arg2):
	    .annotation
	    pass

I would personally prefer to see both types before the def, 
but separated from each other.  I do understand that this 
gets bulky; it scales up better than it scales down.

	note:
	    .name1 = value
	    .name2 = val2
	using:
	    classmethod
	def func(arg1, arg2):
	    pass


>There are several strong arguments to choose (c).

>    1.  The decorator part is optional.  Optional things usually come
>        at the end and shouldn't interrupt non-optional things.

Agreed, but taking it out of the (current) funcdef header clause 
entirely also meets this goal.  The question is whether it would 
still bind tightly *enough* to the funcdef.  

>    4.  When you're reading the body of the function, you will refer
>        to the arguments frequently and the decorators not at all.
>        So the arguments should come first, in the usual position.

classmethod does make a difference, because it changes the signature.
One of Guido's questions is whether there will ever be a long chain 
of *tranforming* decorators.  

We have seen examples of long chains of decorators, but I don't think 
anyone has a concrete use case with more than two *transforming* 
decorators.  If chains really stay short, then

	def classmethod func(arg1, arg2):
	    pass

looks OK.  (Except that new users will assume classmethod is a keyword,
and try to look it up -- which does not work for user-created decorators.)

>    5.  The decorators act on the function after the entire function
>        definition has been evaluated.  It makes sense to arrange the
>        function as a visual unit so you can see what is being created
>        and manipulated.

You can already put them after the full definition; the reason for this
syntax is to move them up so that people can keep them in mind while
reading the definition.

-jJ



More information about the Python-Dev mailing list