Python Forum
Question regarding local and global variables
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Question regarding local and global variables
#1
I'm relatively new to learning Python. I've been reading "Mastering Python". In chapter 2 on Variables it provides an example similar to this:
a = 20
b = 30
c = [1, 2, 3]

def demo():
    a = 21
    b = 31
    c = [4, 5, 6]
    
demo()
So after I run the program and do a print(a,b,c) I get the result as expected

>>> print(a,b,c)
20 30 [1, 2, 3]
So I somewhat understand the scope of variables in reference to global versus local. The variables outside of the def are global and within the def are local. So far so good. But what if I do this:

a = 20
b = 30
c = [1, 2, 3]

def demo():
    a = 21
    b = 31
    c[0] = 5
    
demo()
Now I get this result

>>> print(a,b,c)
20 30 [5, 2, 3]
So if declaring a or b to new values in the def object doesn't change them why does c[0] = 5 change the global list of c without declaring it global within the def object?

Sorry if this seems elemental but this really stuck out to me as I was thinking about some other code that I have been working with.

Thanks.
Don
Reply
#2
Lists are mutable. It's the same object i.e. same id, but because lists sa mutable, the element at index 0 has changed.
c = [1, 2, 3]
print(id(c), c)
 
def demo():
    c[0] = 5
     
demo()
print(id(c), c)
Output:
139939046686920 [1, 2, 3] 139939046686920 [5, 2, 3]
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#3
Before you can subscript a variable, the variable must already exist. So when you do c[0] = 5, it first will search the local scope for c, and not finding it, will search the global scope for c.
If you did
c = [1, 2, 3]
print(id(c), c)
  
def demo():
    c = [1, 2, 3]
    c[0] = 5
      
demo()
print(id(c), c)
You will see that the global c is not changed as there is now a local version created.
Reply
#4
(Apr-12-2020, 02:24 PM)TomToad Wrote: Before you can subscript a variable, the variable must already exist. So when you do c[0] = 5, it first will search the local scope for c, and not finding it, will search the global scope for c.

So in my example a&b already existed outside the object so why are they not found inside as is c ?
Reply
#5
if in the local scope you try to assign to a name that is not being declared global, then it will be local (that is what happening in the first snippet)
In the second snippet you assign to a and b, so they again are local names. For c, you don't assign to c, you assign new value to element with index 0. That's the difference, you don't create new name c within the local scope, so it uses the one from the global scope. see the difference

a = 20
b = 30
c = [1, 2, 3]
print(f'outside, id: {id(c)}, c:{c}')
def demo():
    a = 21
    b = 31
    c = [4, 5, 6]
    print(f'inside, id: {id(c)}, c:{c}')
    c[0] = 7
    print(f'inside, id: {id(c)}, c:{c}')
     
demo()
print(f'outside, id: {id(c)}, c:{c}')
Output:
outside, id: 139836028387528, c:[1, 2, 3] inside, id: 139836028387592, c:[4, 5, 6] inside, id: 139836028387592, c:[7, 5, 6] outside, id: 139836028387528, c:[1, 2, 3]
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#6
So if I do this I see the inside and outside id of a & b are different even though I declared a & b global inside.

a = 20
b = 30
c = [1, 2, 3]
print(id(a),a, id(b),b, id(c),c)

def demo():
    global a
    global b
    a = 21
    b = 31
    c[0] = 5
    print(id(a),a, id(b),b, id(c),c)
    
demo()

>>> %Run test1.py
4428144000 20 4428144320 30 4435940048 [1, 2, 3]
4428144032 21 4428144352 31 4435940048 [5, 2, 3]
Reply
#7
names in python are just pointers, at the beginning name a points to an int object - 20 with id 4428144000
after you call the function name a points to different int object - 12 (i.e. different location in memory, thus different id 4428144032)
as you can see c is pointing to same object, although element at index 0 has changed (which is possible, because lists are mutable objects).

Read this https://nedbatchelder.com/text/names1.html

also
a = 5
b = 5
print(id(a), id(b))
Output:
11381600 11381600
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#8
(Apr-12-2020, 02:44 PM)donmerch Wrote: So if I do this I see the inside and outside id of a & b are different even though I declared a & b global inside.

That is a good question. If you print the values again after demo() is called, you will see that the main values do change when assigned from within the function. But curiously, the ids are overwritten as well which seems to contradict the documentation.
a = 20
b = 30
c = [1, 2, 3]
print("before demo()",id(a),a, id(b),b, id(c),c)
 
def demo():
    global a
    global b
    a = 21
    b = 31
    c[0] = 5
    print("In demo()",id(a),a, id(b),b, id(c),c)
     
demo()
print("After demo()",id(a),a,id(b),b,id(c),c)
Output:
before demo() 140724845310816 20 140724845311136 30 1546429675272 [1, 2, 3] In demo() 140724845310848 21 140724845311168 31 1546429675272 [5, 2, 3] After demo() 140724845310848 21 140724845311168 31 1546429675272 [5, 2, 3]
Quote:id(object)
Return the “identity” of an object. This is an integer which is guaranteed to be unique and constant for this object during its lifetime. Two objects with non-overlapping lifetimes may have the same id() value.

The output does not show a unique and constant id.
Reply
#9
Maybe also read this:
https://docs.python.org/3/faq/programmin...-in-python

Quote:What are the rules for local and global variables in Python?

In Python, variables that are only referenced inside a function are implicitly global. If a variable is assigned a value anywhere within the function’s body, it’s assumed to be a local unless explicitly declared as global.

Though a bit surprising at first, a moment’s consideration explains this. On one hand, requiring global for assigned variables provides a bar against unintended side-effects. On the other hand, if global was required for all global references, you’d be using global all the time. You’d have to declare as global every reference to a built-in function or to a component of an imported module. This clutter would defeat the usefulness of the global declaration for identifying side-effects.
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#10
Ok thanks all for your explanations. I have a lot more to learn obviously. It just stood out to me why one type of object (integer, list) is referred to differently inside and outside a function.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Global variables not working hobbyist 9 1,115 Jan-16-2021, 03:17 PM
Last Post: jefsummers
  Global vs. Local Variables Davy_Jones_XIV 4 692 Jan-06-2021, 10:22 PM
Last Post: Davy_Jones_XIV
  Global - local variables Motorhomer14 11 1,075 Dec-17-2020, 06:40 PM
Last Post: Motorhomer14
  from global space to local space Skaperen 4 915 Sep-08-2020, 04:59 PM
Last Post: Skaperen
  local / global lists RedWuff 1 717 May-26-2020, 03:11 AM
Last Post: deanhystad
  local/global variables in functions abccba 6 1,225 Apr-08-2020, 06:01 PM
Last Post: jefsummers
  Question about naming variables in class methods sShadowSerpent 1 717 Mar-25-2020, 04:51 PM
Last Post: ndc85430
  Creating local variables from a string peckjonk 2 903 Feb-15-2020, 06:07 PM
Last Post: ndc85430
  Where to put the global keyword when assigning variables outside a function? new_to_python 8 1,176 Feb-09-2020, 02:05 PM
Last Post: new_to_python
  Basic Pyhton for Rhino 6 question about variables SaeedSH 1 789 Jan-28-2020, 04:33 AM
Last Post: Larz60+

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020