0

I was experimenting with this code:

def a():
    #global p
    p.append(4);
    d=9

p=[2,3];
d=8
a();
print p  # ----> [2, 3, 4]
print d  # ----> 8

The variable d value is not changed as I didn't use the global keyword. But the list p was modified in function even though I didn't use global. Are all lists global by default in functions?

Ryan Haining
  • 35,360
  • 15
  • 114
  • 174
syam
  • 387
  • 4
  • 19

1 Answers1

1

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
Ryan Haining
  • 35,360
  • 15
  • 114
  • 174
  • Just to clarify, `p` is visible to function `a` even though `p` is not global? This is different than how many other languages would work right? – mitoRibo Aug 18 '16 at 16:47
  • 2
    @rbierman I think you have got the things backwards. **All names defined at the top level of a module are global**. However the whole function declration is a single scope in python, so a name `x` can refer either to a local variable *or* a global one. If you put an assignment to `x` in the function python decides that *all* references to name `x` inside that function body are to that local variable. If no assignment is found then python looks up the enclosing scopes and finds the global name `x`. – Bakuriu Aug 18 '16 at 16:49
  • @rbierman in which example are you saying that `p` is not global? – Ryan Haining Aug 18 '16 at 16:51
  • Thanks Ryan, But In my code, i didnt use global KW. so when the subroutine sees p.append(), how it can modify the global p array? Also in this append case, then what is difference between using global p and not using global p in function as both gives same result of modifying p array? – syam Aug 18 '16 at 16:52
  • @syam since there is no `p` local variable assigned anywhere in `a`, it looks in the enclosing scope for something named `p`. If in your function you had *assigned* to `p` that would introduce a local variable – Ryan Haining Aug 18 '16 at 16:53
  • @syam if all you're doing is calling methods on `p` then it won't make any difference whether or not you use `global`. Keep in mind that every name in python is just a reference to an object, there's not much difference between how the names `a`, `p`, and `d` work in your example. If you always needed to use `global` to access a non-local variable, you'd need a `global` for every function you called! – Ryan Haining Aug 18 '16 at 16:56
  • @Ryan, So in my function 'a', since there is no p variable, it takes it as local. im using p.append(4) inside the function, it should return [2,3] only if i printed p outside the function na ?as p treat as a local i the subroutine a. I have little confusion on this :-) – syam Aug 18 '16 at 16:59
  • @syam since there is no `p` in `a` it takes it as a *global* (slight oversimplification here). Every time you call `a` it will append another `4`. Maybe you'd understand this more if you tried printing `p` inside of `a`? – Ryan Haining Aug 18 '16 at 17:01
  • @syam the lookup ordering follows python's [LEGB rules](http://sebastianraschka.com/Articles/2014_python_scope_and_namespaces.html) – Ryan Haining Aug 18 '16 at 17:03
  • @RyanHaining thanx man... – syam Aug 18 '16 at 17:10
  • @Bakuriu thank you, that makes sense to me now – mitoRibo Aug 18 '16 at 20:40