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

Reply via email to