Speed of Nested Functions & Lambda Expressions
Duncan Booth
duncan.booth at invalid.invalid
Fri Dec 7 04:56:03 EST 2007
Terry Jones <terry at jon.es> wrote:
> Duncan Booth wrote:
>
>> You can use Python's bytecode disassembler to see what actually gets
>> executed here:
>>
>> >>> def fn_outer(v):
>> a=v*2
>> def fn_inner():
>> print "V:%d,%d" % (v,a)
>>
>> fn_inner()
>>
>> >>> import dis
>> >>> dis.dis(fn_outer)
>> 2 0 LOAD_DEREF 1 (v)
> [snip]
[snip]
>
> I'd like to understand what it is that triggers the use of
> LOAD/STORE_DEREF versus LOAD/STORE_FAST. This seems dependent on how
> fn_inner above uses the a and v variables. If I change the print
> "V:%d,%d" % (v,a) line to be something like (a, v) = (v, a) or do
> other simple uses and assignments to a and v, LOAD/STORE_FAST is used.
> It seems that it's the use of print (in this case) that triggers the
> use of LOAD/STORE_DEREF in the bytecode.
> Can anyone shed more light on what in general causes the switch to
> LOAD/STORE_DEREF?
You'll kick yourself for not seeing it.
If you changed fn_inner to:
def fn_inner():
a, v = v, a
then you also changed 'a' and 'v' into local variables. LOAD/STORE_FAST is
used to access local variables, LOAD/STORE_DEREF are used to access
variables in an outer scope.
There is no way in Python 2.x to rebind a name from a nested scope: any
name you use as a target of an assignment is always either a local variable
or a global variable.
(Actually, that's a lie, Google some of my old posts if you want to know
how to rebind a name in a nested scope, but I warn you in advance it is
really hackish and not something you would ever do for real.)
More information about the Python-list
mailing list