3 ms·
> Python uses many dictionaries in the background: among other things, local variables Just a minor correction, Python doesn't use dicts for local variables, `
by _wmd 9y ago
> Python uses many dictionaries in the background: among other things, local variables
Just a minor correction, Python doesn't use dicts for local variables, `locals()` is a lie, it creates a dict from scratch. Internally each frame has an array of locals whose values correspond to the names in the code object's co_locals.
- duskwuff 9y ago> `locals()` is a lie, it creates a dict from scratch. Are you sure? The behavior I see suggests otherwise... >>> a = 1 >>> d = locals() {'a': 1, 'd': {...}} >>> b = 2 {'a': 1, 'd': {...}, 'b': 2} >>> d['b'] = 123 >>> b 123 >>> d is locals() True
- _wmd 9y agoSee PyFrame_FastToLocals() in the CPython source. Try wrapping your code in a function and notice the changes are no longer mirrored. Calls to exec() and eval() cause PyFrame_FastToLocals() to be applied afterwards, as used by the interactive console, but this doesn't happen during normal execution
- sabauma 9y agoThe REPL essentially operates at the global scope, which is represented as a dictionary. Variables local to a function are not stored in a dictionary, however: def main(): a = 1 d = locals() print d d['b'] = 123 print b print d print d is locals() main() Which prints {'a': 1} Traceback (most recent call last): File "test.py", line 23, in <module> main() File "test.py", line 19, in main print b NameError: global name 'b' is not defined
- yorwba 9y agoThat's because the compiler doesn't know the locals() dictionary will be modified at runtime, so it treats b as a global variable (which happens to be undefined). To show that not even changes to existing local variables work, try def main(): a = 1 d = locals() print d b = None d['b'] = 123 print b print d print locals() print d is locals() which prints {'a': 1} None {'a': 1, 'b': 123} {'a': 1, 'b': None, 'd': {...}} True I.e. changes to the dictionary returned by locals() are ignored, and calling locals() again overrides the previous values.
- kpxxx 9y agoWhy this happens has been explained, but more generally what you posted really doesn't prove anything at hand really. The dictionary created from scratch could be made an updateable view by hooking __setitem__. If you gonna contradict with "are you sure?" for something so objectively answered by the source, it might be helpful to think if your example actually demonstrates what you're trying to prove.