decorators and closures

Dave Angel d at davea.name
Mon Nov 21 12:11:30 EST 2011


On 11/21/2011 10:35 AM, Andrea Crotti wrote:
> On 11/21/2011 03:06 PM, Dave Angel wrote:
>> Your function 'nested' isn't nested, 'fun' is. What you discovered is
>> that a decorator is always executed, every time a nested decorated
>> function is defined.
>>
>> You've also ust proved that it would be an incompatible change.
>> Doesn't that answer the question? An optimizer that changes the
>> behavior isn't usually desirable.
>>
> Yes sure I think it makes perfectly sense, because you actually redefine
> a local variable every time..
>
> Another thing (which was also the reason of the subject), I tried to
> disassemble the following:
> def dec(fn):
> def _dec():
> fn()
>
> return _dec
>
> @dec
> def fun():
> print("here")
>
> fun()
>
> And I get this:
> In [29]: dis.dis(test_decorate)
> Disassembly of dec:
> 2 0 LOAD_CLOSURE 0 (fn)
> 3 BUILD_TUPLE 1
> 6 LOAD_CONST 1 (<code object _dec at 0x1c4b930, file "test_decorate.py",
> line 2>)
> 9 MAKE_CLOSURE 0
> 12 STORE_FAST 1 (_dec)
>
> 5 15 LOAD_FAST 1 (_dec)
> 18 RETURN_VALUE
>
> Disassembly of fun:
> 3 0 LOAD_DEREF 0 (fn)
> 3 CALL_FUNCTION 0
> 6 POP_TOP
> 7 LOAD_CONST 0 (None)
> 10 RETURN_VALUE
>
>
> Looking up the definition of the single calls didn't help much, so why
> do we need
> for example MAKE_CLOSURE?
> Is MAKE_CLOSURE just more generic maybe?
>

You didn't mention what version of Python you're running.  With Python 
2, I got very different results.  So I switched to Python 3.2, and I 
still don't get exactly what you have.

A closure is needed if there's some non-global data outside the function 
definition (code object) that's needed by the function object.  As you 
supply the code I don't need a closure.  But if I add a local variable 
in test_decorate(), and refer to it in dec(), then I get one.  Not the 
same as yours.

You left out the import and the definition line for test_decorate.  Did 
you leave anything else?  And what version of Python are you using?  Are 
you perhaps running in a shell, as opposed to running code directly from 
a source file?



-- 

DaveA



More information about the Python-list mailing list