9

I read this code (given below) and my understanding was that, if a variable is declared global inside a function and if it is modified then it's value will change permanently.

x = 15
def change(): 
    global x 
    x = x + 5
    print("Value of x inside a function :", x) 
change() 
print("Value of x outside a function :", x)  

Output:

Value of x inside a function : 20
Value of x outside a function : 20

But the code below shows a different output. How is it that the value of x does not change inside the print("After making change: ", x) and still remains 15

def add(): 
    x = 15
    
    def change(): 
        global x 
        x = 20
    print("Before making changes: ", x) 
    print("Making change") 
    change() 
    print("After making change: ", x) 

add() 
print("value of x",x) 

Output:

Before making changes:  15
Making change
After making change:  15
value of x 20
3
  • 3
    add does not read a global x, it reads the local x created by x = 15. add would have to declare x as global as well. Commented Jul 10, 2020 at 16:05
  • But wouldn't the value of x change permanently when the change() function is called ? Commented Jul 10, 2020 at 16:15
  • 3
    You probably want nonlocal, not global. Commented Jul 10, 2020 at 16:18

3 Answers 3

12

In add, x is not a global variable; it's local to add. You either need to make it global as well, so that add and change are referring to the same variable

def add(): 
    global x
    x = 15
    
    def change(): 
        global x 
        x = 20
    print("Before making changes: ", x) 
    print("Making change") 
    change() 
    print("After making change: ", x) 

add() 
print("value of x",x)

or you need to declare x in change as nonlocal, rather than global.

def add(): 
    x = 15
    
    def change(): 
        nonlocal x 
        x = 20
    print("Before making changes: ", x) 
    print("Making change") 
    change() 
    print("After making change: ", x) 

add() 
print("value of x",x)
Sign up to request clarification or add additional context in comments.

3 Comments

in the second box, the last print("value of x", x) produces a NameError: name 'x' is not defined. pretty understandable as the only x's which come into play are those from add(), i.e. local to add(), and the x from change(), which is preceded by nonlocal, thus referring to the x from add. there's no ''global'' x, thus the print from outside all functions doesn't actually have what to print after the add() function call has finished and the stack has been emptied from any x's. correct?
Yeah, looks like I incorrectly removed the original global declaration from add. Putting it back, I'm not sure there's any difference between global and nonlocal in change, or any reason to use nonlocal instead, so I'm not entirely sure what my point there was. (Probably just blanked on what I was doing in my haste to talk about nonlocal.)
the second option wont work, and you need to use global in both functions. with global + nonlocal you get a SyntaxError: no binding for nonlocal 'x' found
2

Inside the function add the variable x is present in the enclosing scope and not the global scope that's why your variable x won't change even if you use the global keyword.
To change this x you need nonlocal keyword which applies to the variables present in the enclosing scope.

The nonlocal statement causes the listed identifiers to refer to previously bound variables in the nearest enclosing scope excluding globals.


# global scope
x = 0  


def add():
    # enclosing scope
    x = 15

    def change():
        nonlocal x
        x = 20

    print("Before making changes: ", x)
    print("Making change")
    change()
    print("After making change: ", x)


add()
print("value of x", x)  # this x is global variable

Output:

Before making changes:  15
Making change
After making change:  20
value of x 0

Comments

1

when you define global x in change() function, nested in add() function; it defines a main global x variable which is different from local x = 15 at the beginning of the add() function. when you print x before and after calling change(), you actually use local x = 15 at the beginning of add() function, but final print after calling add() will use defined global x which defined in main scope and has the value of 20

more explanation

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.