Variables in Python are just names which refer to objects. In an expression, the name is a stand-in for the actual object. Saying test(x)
means "pass the object referred to by x
into test
". It does not mean "pass the symbol x
into test
".
In addition, re-assigning a name only changes what object that name refers to. It affects neither the object nor any of its aliases.
In short, the name var
you modify inside test
has no relation to x
at all.
The preferred way to have a function change something is by reassigning the result:
x = 2
def change(var):
return var * 2
x = change(x) # x now refers to 4 instead of 2
print(x)
If you want to change a name outside a function, you can use the nonlocal
and global
keywords:
x = 2
def change_x():
global x
x = x * 2
change_x() # x now refers to 4 instead of 2
print(x)
While this can make some trivial problems easy to solve, it is generally a bad idea for larger programs. Using global variables means one can no longer use the function in isolation; results may depend on how often and in what order such a function is called.
If you have some self-contained group of values and means to modify them, a class can be used to describe this:
class XY:
def __init__(self, x, y):
self.x, self.y = x, y
def swap(self):
self.x, self.y = self.y, self.x
my_values = XY(None, 1)
print(my_values.x, my_values.y)
my_values.swap()
print(my_values.x, my_values.y)
In contrast to global
variables, you can create as many isolated instances of classes as needed. Each instance can be worked on in isolation, without affecting the others.
You can also use mutable values to make changes visible to the outside. Instead of changing the name, you modify the value.
x = [2] # x is a mutable list, containing the value 2 at the moment
def change(var):
var[0] = 4 # change leading element of argument
change(x) # x now contains 4 instead of 2
print(x)