def new_val(x):
x['a'] = 5
return x
b = {'a': 2}
b = new_val(b) # b re-assigned to ret val
Since dictionaries are mutable, b is a reference pointer to a dictionary, and we pass this pointer into the function new_val.
The reference to the dictionary doesn't change, but the dictionary's reference to 2 changes to 5.
The original variable b should now have 'a' map to 5. However, I'm wondering whether the reference to the dictionary (in other words, the pointer for variable b) ever changes.
We technically, 're-assign' the reference variable b to a reference that happens to be the same.
At a low level, what happens? Is this like a no-op, where some logic recognizes that the reference is the same, or does the reference actually get unassigned and reassigned?
Maybe a simpler example would be:
b = {}
b = b # At a low level, what does this line do?
b = b
is not a no-op. The data held by previous b
variable is reassigned to a new variable, which name is also b
. So it does nothing but is not ignored.
Don't take my word for it. Let's disassemble your last example instead:
def f():
b = {}
b = b
import dis
print(dis.dis(f))
2 0 BUILD_MAP 0
3 STORE_FAST 0 (b)
3 6 LOAD_FAST 0 (b)
9 STORE_FAST 0 (b)
12 LOAD_CONST 0 (None)
15 RETURN_VALUE
As you see there are 2 operations LOAD_FAST
and STORE_FAST
on b
for that b = b
line. They achieve nothing useful, yet they are executed.