Terry Jones <[EMAIL PROTECTED]> 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.) -- http://mail.python.org/mailman/listinfo/python-list