0

when I reassign a variable inside of the function it assigns only inside it. if you print the same variable outside of the function it is the same it hasn't been reassigned.

x = 5      #assigning x

def sth():
    x = 2
    print(x)    #output : 2

sth()           #calling function
print(x)        #still output : 5

I thought if I call the function it will reassign it but it didn't.

how should I reassign inside of the function so it is reassigned outside too

iammgt
  • 43
  • 1
  • 10
  • Define `x` as `global`. – Abdul Niyas P M Dec 06 '19 at 05:13
  • A function has a separate namespace with its own variables. – Klaus D. Dec 06 '19 at 05:13
  • 3
    First of all, don't do this sort of mutation of global state. `x = 2` is a purely local assignment. Make your functions [pure](https://en.wikipedia.org/wiki/Pure_function)/[idempotent](https://en.wikipedia.org/wiki/Idempotence#Computer_science_meaning). Use parameters and return values--that's what they're for! Ignoring this advice is going to cause extreme quantities of debugging and refactoring agony. – ggorlen Dec 06 '19 at 05:14
  • 2
    I agree with @ggorlen. It is far better to modify the design of your program than dig yourself into a deeper hole because “it works”. – AMC Dec 06 '19 at 05:22
  • Also OP this is an extremely basic programming concept/idea. I strongly recommend learning more before attempting to write anything bigger than tiny programs. – AMC Dec 06 '19 at 05:24
  • Does this answer your question? [Python function global variables?](https://stackoverflow.com/questions/10588317/python-function-global-variables) – Gricey Dec 06 '19 at 05:31
  • @AlexanderCécile I choose a project and start working on it(although I know nothing). on the way of creating it, I learn the concepts that are needed. I think its more efficient. – iammgt Dec 06 '19 at 05:31
  • 1
    @iammgt That’s fine, as long as it doesn’t result in a flood of duplicate or low quality questions on Stack Overflow, you’re all good! :) – AMC Dec 06 '19 at 05:43

2 Answers2

0

This is due to scope of the variable. You can use the below code in order to change value of x.

x = 5      #assigning x

def sth():
    global x    
    x = 2
    print(x)    #output : 2

sth()           #calling function
print(x)        #output : 2

But this is not a good way to perform assignment, As suggested in the comments by @ggorlen, do make sure your functions are pure/idempotent

stud3nt
  • 2,056
  • 1
  • 12
  • 21
0

In Python, you can't reassign a global variable within a function without the global keyword. However, accessing or modifying a global variable is fine.

Accessing global variable

x = 5

def print_x():
    print(x)

print_x()  # prints 5

When the Python interpreter encounters the x variable inside of the function print_x it first looks for it in the list of locals, and then when it doesn't find it, looks for it in the list of globals and finds its value, which is 5.

Modifying a global variable

As I mentioned, you can modify a global variable just fine without doing anything special:

arr = []

def modify_arr():
    arr.append(5)

print(arr)  # prints [5]

Similarly, when the Python interpreter reads arr.append(5) it looks up the variable arr in the locals list, doesn't find it, and then searches the globals list, finds it and calls its append method.

Defining a local variable

x = 5

def flawed_reassign_and_print_x():
    x = 2
    print(x)

flawed_reassign_and_print_x()  # prints 2
print(x)  # prints 5

When the interpreter sees x = 2 it adds a variable called x to the list of local variables with the value 2. Then when it encounters the x to print inside the function, as before it first looks x up in the list of locals and since it finds it, just prints out 2. It never gets to the step of looking for the global x since it found a local one first.

After the function call, x is unchanged.

Reassigning and accessing a global without the global keyword

x = 5

def very_flawed_print_and_reassign_x():
    print(x)
    x = 2

very_flawed_print_and_reassign_x()  # raises an exception!

This is where I have to correct an explanation I gave in the previous section that wasn't quite the whole story. I said "When the interpreter sees x = 2 it adds a variable called x to the list of local variables". But if that were true, this function shouldn't crash, it should just print the global x and then create a local x.

However, what actually happens is that all local variable names are identified before the function runs. So it stores a variable x in the list of locals, but that it hasn't been assigned yet. So when it gets to print(x) it finds x in the list of locals and then raises an error because it hasn't been assigned yet. The very presence of a variable assignment inside a function makes that variable local.

Reassigning and accessing a global with the global keyword (the correct way)

x = 5

def change_and_print_x():
    global x

    x = 2
    print(x)

change_and_print_x()  # prints 2
print(x)  # prints 2

This global declaration tells the interpreter that x should not be added to the list of locals, even though it sees an assignment of x within the function. So all changes update the x in the globals list.

jeremye
  • 1,368
  • 9
  • 19
  • Good explanation, but it's worth mentioning that none of these things should be done in an actual program, assuming you care about understanding what it does. It turns out `flawed_reassign_and_print_x` (OP's original code) is the most reasonable behavior after all. – ggorlen Dec 06 '19 at 05:58