binding a reference to a variable
Bengt Richter
bokr at oz.net
Thu Apr 11 17:33:58 EDT 2002
On Thu, 11 Apr 2002 08:56:32 -0700, Patrick Miller <patmiller at llnl.gov> wrote:
>Bengt writes>
>> >>> def set(name, val, ns=locals()):
>> ... ns[name]=val
>> ... return val
>
>Bengt noted that 'ns' is local to the declaration module of the
>'def set.'
>
I also noted
"Of course, def set ... must be executed where it can capture ns=locals()
for use inside the function, where locals() is another space (and read-only)."
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
... i.e., that locals() inside a function is different and read-only,
which would predict the following.
>The workaround for that is
>
>def set(name,val):
> import sys
> ns = sys._getframe().f_back.f_locals # local dictionary of caller
> ...
>
>BUT WARNING!!!!! There is a bigger problem -- Changes to the local
>dictionary are NOT reflected in the state of the execution.
>
unless locals() is globals() => 1
as is apparently normally the case at module scope, e.g.,
+---< locagloba.py >-------------
|print 'locagloba id(locals())=%s, id(globals())=%s' % (id(locals()), id(globals()))
|def set(name, val, ns=locals()):
| ns[name]=val
| return val
|set('z',456)
|print z, locals()['z']
+--------------------------------
Python 2.2 (#28, Dec 21 2001, 12:21:22) [MSC 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import locagloba
locagloba id(locals())=8029232, id(globals())=8029232
456 456
>>> locagloba.z
456
>>> print 'interactive id(locals())=%s, id(globals())=%s' % (id(locals()), id(globals()))
interactive id(locals())=7989472, id(globals())=7989472
>>> locals() is globals()
1
>>> locagloba.z
456
OTOH, might as well use globals() in the first place ;-)
>The following does not work as intended....
>
>def f():
> a = 7
> L = locals()
> print L.keys() # Prints ['a','L'] or some such
> L['a'] = 99 # Update the value in L
> print a # But wait! This prints out '7'
>
>The issue is the implementation of the code object supporting f.
>The value of the locals dictionary is created on the fly by
>the call to locals(). The actual values of the local variables
>are on a tiny, predefined stack frame that is used by the bytecode
>interpreter wherein local variables are known only by an
>integer offset.
>
>Creating true "local" variables is astonishly tricky.
>
>You can actually figure out where names map into the frame instance
>(weave does (or will do) it), but it is messy and very implementation
>dependent.
>
But hiding that mess is the job of an implementation ;-)
>From what's been posted, ISTM that making locals() read/write
inside a function is feasible, with a performance hit. Probably
no one has wanted it badly enough to do it at all, never mind finding
a way to penalize only the locals()-modifying users.
Regards,
Bengt Richter
More information about the Python-list
mailing list