22

The documentation for the locals() function specifically warns not to modify its output, as interpreters may not reflect changes in the local scope. I'm assuming that means the Python spec doesn't require it, even though it works in CPython.

I'd like to know if this is the same for globals(). There's no warning in the documentation, but I find it strange that this would differ as each function apparently performs the same action on a different scope.

If it's safe, modifying globals()' output would improve the simplicity and compatibility of a project I'm working on.

trss
  • 855
  • 1
  • 15
  • 31
rspeed
  • 1,482
  • 14
  • 20
  • 8
    "modifying globals()' output would improve the simplicity and compatibility". That's very hard to understand. You should probably ask the **real** question about this "simplicity and compatibility" topic and forget about playing weird games with `globals()`. – S.Lott May 11 '11 at 03:11
  • Two reasons: 1. That would be an incredibly complicated question which would be unlikely to get any useful responses. 2. Other than the compatibility issues, I'm not having difficulty with that portion of the project. Further, fixing those issues isn't possible due to the association of another library. I'm simply weighing a number of different options, and when this question was asked the only important factor was whether or not it was safe to edit global variables using the output of globals(). – rspeed May 11 '11 at 05:05
  • 2
    @rspeed: I ask because this kind of thing of reveals a "rat-hole of lost time". Pursuing a less-than-ideal solution all the way to a dead-end that doesn't really work well. In some cases, it's better to stop trying and do something simpler. (1) "That would be an incredibly complicated question" indicates that something might be wrong with the whole approach and (2) "fixing those issues isn't possible " also indicates something could be wrong with the whole approach. – S.Lott May 11 '11 at 09:56
  • 1
    Well, if you're so inclined, feel free to take a look at the project: https://github.com/rspeed/Django-MetaSettings The code in question is the method used to maintain the scope while (essentially) combining multiple Django settings files. That scope is exactly what globals() returns when run inside settings.py. – rspeed May 12 '11 at 07:32
  • @rspeed: We combine multiple settings files using `import`. – S.Lott May 12 '11 at 09:43
  • 1
    ``import`` doesn't let you maintain the scope without having the more specific settings files import the less specific files. That solution is to inflexible for some projects I've worked on. – rspeed May 12 '11 at 19:33
  • @rspeed. "That solution is too inflexible"? Really? I hadn't noticed any flexibility issue at all. The "specific extends general" works for class definitions and other module definitions pretty nicely. And it works for Django settings just like extending another module or a class definition. I haven't found a problem with it. My point isn't that you're wrong. My point is that a lot of very clever programming may not be helpful. A few dumb rules might be simpler and cheaper than a lot of very clever programming. – S.Lott May 12 '11 at 19:49
  • 1
    It's inflexible because there's no way to build rules which specify which settings to load in which environments. Further, the stack of settings has to be the same on every machine. There are situations where some intermediate settings file shouldn't be loaded. – rspeed May 15 '11 at 00:46
  • @rspeed: The settings which have an import define what they override. The settings can be easily made machine specific through a trivial naming convention. – S.Lott May 15 '11 at 15:40

1 Answers1

27

Modifying locals() doesn't work reliably, even in CPython. It happens to work in module and class scopes, but it fails inside a function (any modifications "won't take", since locals() provides a copy of the local namespace in that case, rather than a reference to the real thing)

However, globals() is different, since that always refers to the module namespace, and module namespaces are required to behave like ordinary dictionaries. So yes, the lack of a warning on globals() isn't an oversight, it really is allowed.

ncoghlan
  • 35,440
  • 8
  • 67
  • 77