There are a couple different things that come up when looking at your code:
Mutable vs. Immutable Data Types
As mentioned in Python's reference:
The value of some objects can change. Objects whose value can change are said to be mutable; objects whose value is unchangeable once they are created are called immutable. (The value of an immutable container object that contains a reference to a mutable object can change when the latter’s value is changed; however the container is still considered immutable, because the collection of objects it contains cannot be changed. So, immutability is not strictly the same as having an unchangeable value, it is more subtle.) An object’s mutability is determined by its type; for instance, numbers, strings and tuples are immutable, while dictionaries and lists are mutable.
So, in the case of home = 0
, 0
is a number so it is immutable.
Pass by Assignment
In Python, (almost) everything is an object. What we commonly refer to as "variables" in Python are more properly called names. Likewise, "assignment" is really the binding of a name to an object. Each binding has a scope that defines its visibility, usually the block in which the name originates. Jeff Knupp goes over this in more depth with more example in this blog post.
What happens in your code...
So, when you have home = 0
, now we know that the name home
points to the immutable number 0
. When you call basestate(home)
, the local name base
is assigned the same object that b
is pointing to; the 0
. At this point, id(home) == id(b)
(In CPython, id(object) is the address of the object in memory.). However, when you say base = 1
(or base = 0
), then since numbers (int
in this case) are immutable, the name base
is assigned a new number object 1
. The old 0
object is still reference by home
but not by base
. So, now id(home) != id(base)
because their are no longer pointing to same place in memory.
So, you are assigning 1
(or 0
) to base
and as soon as the function exits, base
is no longer in scope and it hasn't changed anything else like home
because numbers are immutable.
So what do I do?
You need to return the required value and re-assign it to home
:
home = 0
def basestate(base):
return 1 if base == 0 else 0
basestate(home)
print(home)
P.S. Don't use is
for that kind of comparison. In general, you use ==
when comparing values and is
when comparing identities. In this case you are comparing values. But in the case where I said id(home) == id(base)
, I could have said home is base
P.P.S Using id()
on small numbers is actually quite cunning because the current CPython implementation keeps an array of integer objects for all integers between -5 and 256, when you create an int in that range you actually just get back a reference to the existing object.
I hope this help!