Assignment in Python
00:00 Since Python’s argument passing mechanism relies so much on how Python deals with assignment, the next couple of lessons will go into a bit more depth about how assignment works in Python.
00:12 Recall some things I’ve already mentioned: Assignment is the process of binding a name to an object. Parameter names are also bound to objects on function entry in Python. And again, this is how Python’s argument passing mechanism gets its name.
00:29 But how exactly does that work?
00:33 Let’s take a closer look.
00:36
In other languages like C++, assignment is quite simple, especially for basic types. In the first statement, a space of memory which has been designated for the variable x
has the value 5
stored in it.
00:51
Then, in that second statement, that same piece of memory is overwritten with the value of 10
, and the value 5
is lost completely.
01:01
Python works much differently. In the first statement, an object representing the number 5
is created, if one doesn’t already exist, and then x
is made to refer—or we sometimes say “point”—to that object, basically by storing the memory address to where the object 5
is stored.
01:21
In the second statement, x
is reassigned to refer to an object representing the value 10
. Again, if one didn’t already exist, one is created.
01:31
In other words, x
is rebound to a new object. The object representing 5
may still exist because there could be other variables or names referring to that object.
01:42
Let’s look at this process in more detail. There’s a particular structure used to implement objects in Python. A reference counter keeps track of how many references a specific object has. So again, in the statement x = 5
, an object representing the value 5
is found or created, the reference counter for that object is incremented, and an entry is made binding that variable name to the object.
02:14
This is basically done in a dictionary, and depending on the namespace of the variable, it can be found using either the locals()
or globals()
function.
02:26
Then, when x
is reassigned to the value 10
, the reference count for the object representing 5
is reduced by one, the reference counter for the object representing 10
is increased by one, and finally, the appropriate dictionary is updated to indicate that x
is now bound to that new object 10
. To see this happen, you can write a small program which uses the sys.getrefcount()
function.
02:54
This function takes an object as an argument and returns the number of references to it. Here is an example. It will track the number of references to two objects, cleverly named "value_1"
and "value_2"
. First, it displays the number of references to each object before either are assigned to a variable.
03:20
Then it assigns x
to be bound to the "value_1"
. It repeats calls to getrefcount()
to see how the counts have been changed as a result of that assignment statement.
03:33
Then it reassigns x
from "value_1"
to "value_2"
and displays the ref counts again. Let’s try this out.
03:48
Well, that’s interesting! Before either object is bound to x
, they each already have three references. Why is that? Well, one is an internal reference to the object when it was created.
04:01
Python has to know where it is so it can be bound to something else as the program runs. Second, it’s being used as an argument to this function call, so there’s a reference. And it’s used in the parameter variable inside getrefcount()
.
04:17
So you likely always get a count of at least 3
for any object you try. The point to notice is that once x
was assigned to be "value_1"
, the ref count for "value_1"
was incremented.
04:32
Then when x
was reassigned to "value_2"
, the ref count for "value_1"
went back down to 3
and the ref count for "value_2"
increased to 4
.
04:44
So, you can see the ref counts are going up and down as objects are bound and unbound to the variable x
.
04:54 Next, you’ll see how this notion of assignments and bindings works with function arguments.
Become a Member to join the conversation.