What happens when you assign the value of one variable to another variable in Python?

Viewed 63319

This is my second day of learning python (I know the basics of C++ and some OOP.), and I have some slight confusion regarding variables in python.

Here is how I understand them currently:

Python variables are references (or pointers?) to objects (which are either mutable or immutable). When we have something like num = 5, the immutable object 5 is created somewhere in memory, and the name-object reference pair num is created in a certain namespace. When we have a = num, nothing is being copied, but now both variables refer to the same object and a is added to the same namespace.

This is where my book, Automate the boring stuff with Python, confuses me. As it's a newbie book, it doesn't mention objects, namespaces, etc., and it attempts to explain the following code:

>>> spam = 42
>>> cheese = spam
>>> spam = 100
>>> spam
100
>>> cheese
42

The explanation it offers is exactly the same as that of a C++ book, which I am not happy about as we are dealing with references/pointers to objects. So in this case, I guess that in the 3rd line, as integers are immutable, spam is being assigned an entirely new pointer/reference to a different location in memory, i.e. the memory that it was initially pointing to wasn't modified. Hence we have cheese referring to the initial object referred to by spam. Is this the correct explanation?

10 Answers

In Python, a variable holds the reference to the object. An object is a chunk of allocated memory that holds a value and a header. Object's header contains its type and a reference counter that denotes the amount of times this object is referenced in the source code so that Garbage Collection can identify whether an object can be collected.

Now when you assign values to a variable, Python actually assigns references which are pointers to memory locations allocated to objects:

# x holds a reference to the memory location allocated for  
# the object(type=string, value="Hello World", refCounter=1)

x = "Hello World" 

Now when you assign objects of different type to the same variable, you actually change the reference so that it points to a different object (i.e. different memory location). By the time you assign a different reference (and thus object) to a variable, the Garbage Collector will immediately reclaim the space allocated to the previous object, assuming that it is not being referenced by any other variable in the source code:

# x holds a reference to the memory location allocated for  
# the object(type=string, value="Hello World", refCounter=1)

x = "Hello World" 

# Now x holds the reference to a different object(type=int, value=10, refCounter=1)
# and object(type=string, value="Hello World", refCounter=0) -which is not refereced elsewhere
# will now be garbage-collected.
x = 10

Coming to your example now,

spam holds the reference to object(type=int, value=42, refCounter=1):

>>> spam = 42

Now cheese will also hold the reference to object(type=int, value=42, refCounter=2)

>>> cheese = spam

Now spam holds a reference to a different object(type=int, value=100, refCounter=1)

>>> spam = 100
>>> spam
100

But cheese will keep pointing to object(type=int, value=42, refCounter=1)

>>> cheese
42

numpy.copy() function page has an explanation

https://docs.scipy.org/doc/numpy/reference/generated/numpy.copy.html

The example it gives is as follows:

Create an array x, with a reference y and a copy z:

x = np.array([1, 2, 3])
y = x
z = np.copy(x)

Note that, when we modify x, y changes, but not z:

x[0] = 10
x[0] == y[0]
True
x[0] == z[0]
False
Related