def index(self):

Duncan Booth duncan.booth at invalid.invalid
Fri Dec 22 03:40:18 EST 2006


"Gert Cuykens" <gert.cuykens at gmail.com> wrote:

> On 21 Dec 2006 09:44:48 GMT, Duncan Booth
> <duncan.booth at invalid.invalid> wrote: 
>> "George Sakkis" <george.sakkis at gmail.com> wrote:
>>
>> @expr
>> def fn(...): ...
>>
>> is exactly equivalent to:
>>
>> def fn(...): ...
>> fn = (expr)(fn)
>>
> 
> ok i did my homework reading about decorators
> http://www.python.org/doc/2.4.4/whatsnew/node6.html
> 
> could it be the example above needs to be like
> 
> @expr
> def fn(...): ...
> 
> is exactly equivalent to:
> 
> def fn(...): ...
> fn = expr(fn)

no it doesn't *need* to be like that, but it *could* be written like that. 
It is true that the parentheses I used are redundant (I thought they made 
my point clearer), but removing redundant parentheses doesn't actually 
change the meaning at all.

In any case, either of these rewrites is an approximation. There is no 
Python code you can write which is exactly equivalent to, but doesn't use, 
the decorator syntax. A closer approximation would be:

If you consider:

    def fn(...): ...

is equivalent to writing:

    fn = new.function(somecodeobject, globals(), 'fn', (...default argument 
expressions...), ...and maybe a closure...)

then:

   @expr
   def fn(...): ...

is equivalent to writing:

   __anonymous_temp_1 = expr
   __anonymous_temp_2 = new.function(somecodeobject, globals(), 'fn', 
(...default argument expressions...), ...and maybe a closure...)
   fn = __anonymous_temp_1(__anonymous_temp_2)

but I don't think that is really any clearer.

It does perhaps indicate the order in which things happen more clearly: 
decorator expression is evaluated, then default arguments, then function is 
created, then decorator is called, then finally the result is assigned to a 
variable with the same name as the function.



More information about the Python-list mailing list