3 ms·
When the name `a` is assigned the value of `baz`, Python is setting a key name `a` in the local dictionary (hash table) `locals()`. Basically `a = 1` is syntac
by rectangletangle 9y ago
When the name `a` is assigned the value of `baz`, Python is setting a key name `a` in the local dictionary (hash table) `locals()`.
Basically `a = 1` is syntactic sugar for `locals()['a'] = 1`
>>> a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
>>> locals()['a'] = 113
>>> a
113
>>>
One interesting side-effect of this is you can assign names that are not valid Python syntax explicitly.
For example:
>>> locals()['foo-bar'] = 1
>>> locals()['foo-bar']
1
>>> foo-bar
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'foo' is not defined
>>>
The name `foo-bar` can't be literally referenced, because the interpreter attempts to interpret it as the subtraction operation `foo - bar`.
- hueving 9y agolocals() is presented to the user as a dictionary, but is that the way cpython actually works with it internally? I've run into weird GC issues that imply it's not a normal dictionary and it's just presented to the user as one for programattic access.
- rectangletangle 9y agoThat's a good question, I'm pretty sure it's not a normal dictionary. However, I'd have to go through the CPython source to confirm. Maybe someone who's more familiar with CPython's implementation will chime in.
- deleted 9y ago[deleted]
- klodolph 9y agoNo, that's not how it works internally. The Python compiler resolves all local variables at compile-time. You can see this for yourself by defining a simple function f, import dis, and calling dis.dis(f). Global variables use a dictionary, however. The disassembly actually looks similar for both.
- adrian17 9y agoThis only works in global scope. It won't work in a function: def f(): a = 5 locals()['a'] = 6 print(a) # 5 Inside a function, accesses/writes of locals use an internal array of local variables, to skip dicts. Same with constants. See: https://github.com/python/cpython/blob/master/Python/ceval.c#L1190 https://github.com/python/cpython/blob/master/Python/ceval.c...