Search code examples
pythonscopenamespacesgloballocal

Writing to locals() works in contrast to documentation saying its not


I am currently tinkering with the variable scopes and how they can be modified / copied, as I would like to postprocess some results dynamically in IPython. The confusion about locals(), vars() and globals() is real for me right now. Especially because the output of this piece of code:

Python 3.6.1 (v3.6.1:69c0db5050, Mar 21 2017, 01:21:04) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> locals()["test"] = 5
>>> print(test)
5

According to the more than brief documentation this should not be possible in my understanding:

Note, the locals dictionary is only useful for reads since updates to the locals dictionary are ignored.

(which is for whatever reason stated in the description of the vars() function)

I hope someone can enlight me :)


Solution

  • Where are you reading this? Both Py 2 docs and Py 3 docs have the following disclaimer:

    Note: The contents of this dictionary should not be modified; changes may not affect the values of local and free variables used by the interpreter.

    This shows exactly what this is: an implementation detail. Sure, it works in CPython, but it might not work in the various other interpreters, like IronPython and Jython. It's what would be called a hack.

    Do not rely on it updating any variables. Do not even try to do it for anything serious, as it causes undefined behaviour.

    In CPython 3.6.0, help(locals) has the following note:

    NOTE: Whether or not updates to this dictionary will affect name lookups in
    the local scope and vice-versa is *implementation dependent* and not
    covered by any backwards compatibility guarantees.
    

    CPython 2.7.13 has no such note, however.