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 -- http://mail.python.org/mailman/listinfo/python-list