[Python-Dev] method decorators (PEP 318)
Phillip J. Eby
pje at telecommunity.com
Fri Mar 26 11:07:17 EST 2004
At 07:10 AM 3/26/04 -0800, Guido van Rossum wrote:
>So, anyway, here's a new suggestion (inspired by Robert's proposal):
>
>(1) Put decorators of the first category early in the def statement,
> for example here:
>
> def foobar [classmethod] (cls, foo, bar):
> ...
>
>(2) Invent some other notation for setting function attributes as part
> of the function *body*, before the doc string even.
>
>For (2) I am thinking aloud here:
>
> def foobar(self, arg):
> @author: "Guido van Rossum"
> @deprecated
> pass
Who is the metadata *for*? Is it just for a human readers and
documentation tools? Or is it intended for machine consumption as well?
If it's for the machine, IMO it should be the same syntax, without a new
construct. If it's for humans and documentation tools, why shouldn't it go
in the docstring?
I guess I don't understand why you see these use cases as so different from
each other as to deserve different syntax, but not different enough to just
use the docstring. In other words, why not simply treat:
def foobar(self, arg) [
info(author="Guido van Rossum", deprecated=True)
]:
pass
as a straightforward application of the same mechanism? Why make people
have to learn two mechanisms, one of which is limited to function
attributes, and the other of which is awkward to use with multiple items?
C# and Java aren't dynamic languages - they don't treat functions or
methods as first class objects, so of course they don't support any sort of
transformation, and are limited to passive metadata in their attribution
syntax. But dynamic frameworks in Python want to be able to have "active
attribution". A number of people here have presented examples of things
where they want to have decorators call a framework function to register
the current function, method, or class in some way. Function attributes
don't support this - you still have to call something afterwards.
I don't believe that the interest in decorators is simply to support
classmethod et al, or to have a way to do function attributes. Instead,
they're a workaround for the fact that Python function definitions aren't
expressions. Otherwise, we'd be doing things like this monstrosity:
foobar = classmethod(
def (self,arg):
pass
)
Obviously, I'm not arguing that Python should look like Lisp. The current
decorator syntax patch is *much* easier to read than wrapping an entire
function definition in parentheses. But the semantics that I think most
people are asking for with decorators, is the simple Lisp-like capability
of applying transformations to a function, but with a more Pythonic
syntax. That is, one where flat is better than nested, and readability
counts. That is the use case that decorators are intended to serve, IMO,
and I believe that this is what most other proponents of decorators are
after as well.
Function attributes, on the other hand, don't really address these use
cases. I would ask, how much field use of function attributes exists
today? Versus how much use of built-in and homemade decorators? There are
lots of the latter, and very few of the former. I would also guess that
where people are using function attributes, there's a good chance that
they're using decorators as well, since they probably need to *do*
something with the attributes. Considering that both function attributes
and decorators have the same overhead today for use (i.e., put them at the
end, no special syntax available), that would suggest that the need/desire
for decorators is much greater than the need for mere metadata annotation.
More information about the Python-Dev
mailing list