2

Why does creating/modifying a member of locals() not work within a function?

Python 2.5 (release25-maint, Jul 20 2008, 20:47:25)
[GCC 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)] on linux2
Type "help", "copyright", "credits" or "license" for more information.

>>> # Here's an example of what I expect to be possible in a function:
>>> a = 1
>>> locals()["a"] = 2
>>> print a
2

>>> # ...and here's what actually happens:
>>> def foo():
...  b = 3
...  locals()["b"] = 4
...  print b
...
>>> foo()
3
RobM
  • 8,373
  • 3
  • 45
  • 37
  • 1
    Why would you want to do this kind of thing? – S.Lott Mar 26 '09 at 17:48
  • I wanted to initialise a load of variables using data fetched externally. So my idea was: 1 Declare all variables as "= None" 2 Create a mapping of varname -> external source path 3 Iterate map, setting variables or aborting with an error But I ran into problems setting my variables. – RobM Mar 27 '09 at 11:39
  • Sorry to revive an old question, but I want to do the same thing: I have a dict, and I want to turn all the elements of the dict into local variables (so I can say foo instead of options.foo). I'm using eval to do this now, but it is ugly. Is there no other way? – GaryO Dec 02 '10 at 14:35
  • @garyo: That should probably be another question, but here's what I came up with to create a new local called `mwahaha` and set it to `"thingy"`: `import inspect; inspect.stack()[0][0].f_locals["mwahaha"] = "thingy"`.Unlikely to work on Jython or IronPython though. – RobM Jan 18 '11 at 16:59

2 Answers2

7

Why would it? It's designed to return a representation, and was never intended for editing the locals. It's not ever guaranteed to work as a tool for such, as the documentation warns.

Devin Jeanpierre
  • 92,913
  • 4
  • 55
  • 79
  • Ah, I missed that because I only read the online help(). Thanks. – RobM Mar 26 '09 at 17:23
  • @Devin, because that would be the least surprising behavior, esp since you can modify globals in a similar way. – allyourcode Oct 17 '09 at 05:34
  • 1
    This is a fair complaint. For what it's worth, it works this way because Python speeds up local access in a way that makes this impossible, whereas the global namespace makes no such optimization (though that has been suggested, e.g. PEP 266). It is arguably a leaky abstraction that should go away. My personal preference would be to make globals() work the way locals() does now, rather than make locals() work like globals() does now. Regardless, my answer was more of a sneaky reference to the docs than a reference to intuition. It wouldn't do it because the docs don't say it should. – Devin Jeanpierre Oct 17 '09 at 23:46
3

locals() return a copy of the namespace (which is the opposite of what globals() does). This means that any change you perform on the dictionary returned by locals() will have no effect. Check in dive into python at example 4.12.

Stefano Borini
  • 138,652
  • 96
  • 297
  • 431