The critical difference is the assignment here. You are fine calling methods on existing global objects, but you can't assign to them without calling them global
. In your code, the name d
is being reassigned to reference another value. If you changed p
with assignment you'd have a similar result
def a():
p = [5, 7] # new local variable, doesn't change global
p.append(9) # doesn't change global p
This makes sense if you think about what happens when python encounters the name for the first time. In the function you've provided, python will see p.append
and say "hm, I don't have a local by the name p
, let me look in the enclosing scope." It sees the global p
and uses that.
In the example I've shown, python will say "there's no explicit global
so I assume this is supposed to be a new local variable." and create one.
Names in python are just references. If python followed the behavior you are expecting you'd need a global
for every function you called, let me explain:
def a():
p.append(1) # I should need 'global p' to do this
This would mean if you had
def g():
...
def f():
g() # this would also need 'global g', otherwise how does it see g?
def f2():
global g
def g(): # changes the global g function
return 0