Anonymus functions revisited

Kay Schluehr kay.schluehr at gmx.net
Wed Mar 23 06:43:31 EST 2005


Duncan Booth wrote:

> Do I really need to mention that the whole concept here is broken.
This
> only works if you call it from global scope. If you call it from
inside a
> function it [usually] won't work:
>
> >>> def makeVars(**nameVals):
>         sys._getframe(1).f_locals.update(nameVals)
>
>
> >>> def test():
> 	try: b
> 	except NameError: print "Before makeVars: NameError"
> 	else: print "Before makeVars: Not NameError"
> 	makeVars(b=2)
> 	try: b
> 	except NameError: print "After makeVars: NameError"
> 	else: print "After makeVars: Not NameError"
>
>
> >>> import sys
> >>> test()
> Before makeVars: NameError
> After makeVars: NameError
> >>>

Yes.

To put it short:

def makeVars(**nameVals):
    print "prev",sys._getframe(1).f_locals["z"]
    sys._getframe(1).f_locals.update(nameVals)
    print "post",sys._getframe(1).f_locals["z"]

def test():
    z = 0
    makeVars(z=2)

>>> z = 0
>>> makeVars(z=3)
prev 0
post 3

>>> test()
prev 0
post 0


The Python runtime uses the opcodes STORE_FAST and LOAD_FAST to
store/access local variables of a function.

Take a closer look at the code:

case STORE_FAST:
    v = POP();
    SETLOCAL(oparg, v);
    goto fast_next_opcode;

with

register PyObject **fastlocals

and macros

#define GETLOCAL(i)	(fastlocals[i])
#define SETLOCAL(i, value) do { PyObject *tmp = GETLOCAL(i); \
				GETLOCAL(i) = value; \
                                Py_XDECREF(tmp); } while (0)

The local variables will be stored in the pointer array fastlocals not
within a Python dict.

If a variable is created as a global it will be stored using the
STORE_NAME opcode instead:


case STORE_NAME:
    w = GETITEM(names, oparg);
    v = POP();
    if ((x = f->f_locals) != NULL) {
    	if (PyDict_CheckExact(x))
    		err = PyDict_SetItem(x, w, v);
    	else
    		err = PyObject_SetItem(x, w, v);
    	Py_DECREF(v);
    	if (err == 0) continue;
    	break;
    }


which clearly accesses a Python dict for storage.


Regards Kay




More information about the Python-list mailing list