PEP 318: Decorators last before colon

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

using: classmethod def func(arg1, arg2): pass
The one major problem that i can see with this kind of syntax is that it is a /special case/ when standard Python block structure does not apply. At least when using 'with' (which I'm not particularly fond of), block structure applies, and makes a moderate amount of sense in Python. The above 'using' keyword and organization lacks any sort of Pythonic flavor (IMO). If we were to stick with standard Python block structure, the 'using' syntax should really be... using: classmethod def funct(arg1, arg2): pass I think this syntax makes more conceptual sense, sticks with standard Python block structure, etc. However, I think that what Ka-Ping has listed as case 'c' makes measureably more sense than any nested or non-nested block structure for decorators. - Josiah
participants (2)
-
Jewett, Jim J
-
Josiah Carlson