[Python-ideas] Tweaking closures and lexical scoping to include the function being defined
Stephen J. Turnbull
stephen at xemacs.org
Sat Oct 1 20:57:19 CEST 2011
Ron Adam writes:
> Supposedly the @ decorator syntax is supposed to be like a pre-compile
> substitution where..
>
> @decorator
> def func(x):x
>
> Is equivalent to...
>
> def func(x):x
> func = decorator(func)
>
> IF that is true,
It is.
> it doesn't make the python core more complex. It would
> just be a source rewrite of the effected block in memory just before
> it's compiled.
>
> But it seems it's not implemented exactly that way.
>
> def deco(func):
> def _(f):
> return func(f)
> return _
>
> @deco(foo)
> def foo(f):
> return f
>
> print(foo('python'))
>
> Results with ... NameError: name 'foo' is not defined
This is different syntax, whose interpretation is not obvious from the
simpler case. For example, by analogy to method syntax it could mean
def foo(f):
return f
foo = deco(foo, foo)
(where the first argument is implicit in the decorator syntax = the
function being decorated, and the second is the explicit argument), in
which case you would have gotten a "too few arguments" error instead,
but it's doesn't. In fact, it is defined to be equivalent to
bar = deco(foo)
@bar
def foo(f):
return f
Ie,
bar = deco(foo)
def foo(f):
return foo
foo = bar(foo)
(which makes the reason for the error obvious), not
> def foo(f):
> return f
> foo = deco(foo)
I guess in theory you could think of moving the evaluation of
deco(foo) after the def foo, but then the correct equivalent
expression would be
def foo(f):
return f
foo = deco(foo)(foo)
which I suspect is likely to produce surprising behavior in many
cases.
More information about the Python-ideas
mailing list