Decorator Dissection

"Martin v. Löwis" martin at v.loewis.de
Sun Apr 3 01:32:09 EST 2005


Ron_Adam wrote:
> I wasn't aware that the form:
> 
> 	result = function(args)(args)
> 
> Was a legal python statement.
> 
> So python has a built in mechanism for passing multiple argument sets
> to nested defined functions! (click)  Which means this is a decorator
> without the decorator syntax.

No. There is no mechanism for passing multiple argument sets to
nested functions. Instead, functions are objects, which can be
assigned to variables, passed as arguments to other functions,
and returned:

 >>> len
<built-in function len>
 >>> other=len
 >>> other([1,2,3])
3
 >>> other
<built-in function len>

Here, len is *an object* that gets *assigned to* the variable other.
The grammatical construct

    <something>(<list of something>)

is evaluated as follows:

1. evaluate <something>. Evaluation always returns an object,
    be it 1+2, other, or f(x).
2. evaluate <list of something>, from left to right.
3. call the object returned in step 1, with the arguments
    computed in step 2.

Because the something before the parentheses can be any expression,
you can also write things like

 >>> items=[]
 >>> items.append(len)
 >>> items[0](range(10))
10

Functions as parameters and return values are not much different:

 >>> def identity(x):
...   return x
...
 >>> identity(len)(range(10))
10

Now, a nested function is locally defined, but then the function
is returned

 >>> def getlenfun():
...   def lenfun(o):
...     return 2*len(o)
...   return lenfun
...
 >>> getlenfun()(range(10))
20

Here, first getlenfun() is evaluated, returning a function lenfun.
Then, range(10) is evaluated, returning a list. Then, lenfun is
invoked with this list.

So far, this has nothing to do with decorators.

> So this isn't a decorator question any more.  Each argument gets
> passed to the next inner defined function,  via... a stack(?)  ;)

No, functions are objects. Notice that in step 1, the object returned
doesn't have to be a function - other things are callable, too, like
types, classes, and objects implementing __call__.

Regards,
Martin



More information about the Python-list mailing list