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.