Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Hint: You can adjust the default video playback speed in your account settings.
Hint: You can set your subtitle preferences in your account settings.
Sorry! Looks like there’s an issue with video playback 🙁 This might be due to a temporary outage or because of a configuration issue with your browser. Please refer to our video player troubleshooting guide for assistance.

Variables in C vs Python

In this lesson, you’ll learn the fundamental differences between variables in C and Python. Technically, Python has names rather than variables, but you can still use the term variable. That’s an important distinction when you’re dealing with memory in Python.

00:00 Earlier in this course, you saw how you could declare and initialize an integer variable in C. As I mentioned earlier, three things happen under the hood: C allocates enough memory for an integer, it assigns the value 2337 to that space in memory, and then indicates that x points to that space in memory. In diagram form, that might look something like this.

00:28 Keep in mind that the actual memory location would normally be a hexadecimal address, much longer than 7f1. What’s interesting about C is that it actually treats the integer as a mutable type.

00:44 This means that we could change the value of x and it would actually overwrite the previous value without having to create a duplicate integer in memory with the new value.

00:56 This code can be used to create a new integer value y that contains a copy of whatever is stored in x. x is copied by value into y.

01:08 This means that x and y now occupy two entirely different spaces in memory,

01:15 but those different spaces contain the same value. Each value can be modified independently of one another. Moving back over to Python, we see that things work a little differently.

01:29 In fact, Python doesn’t even technically have variables. It has what’s called names. This is a pedantic point, and you should never find yourself in any trouble for calling a Python name “a variable,” but it’s a distinction that’s important to make when dealing with memory in Python. Here’s a line of Python code that assigns the name x to the value 2337.

01:56 What’s really going on under the hood is a little bit more complex than with C. That’s because the standard interpreter for Python is written in C and so all the Python code we write eventually is represented as if we wrote it in C. First, the CPython interpreter, which is the standard interpreter written in C, will create what’s called a PyObject in memory.

02:24 The PyObject is like a container for keys and values, a little bit like a dictionary in Python. The type is set to integer and its value is set to 2337.

02:38 Then, a Python name is created, called x, and that points to this PyObject. Because there’s now a name referencing it, the PyObject’s reference count increases to 1.

02:53 This shows that the Python name x doesn’t actually own any space in memory with a value. It merely references a space in memory called a PyObject, and somewhere in that PyObject is the actual value.

03:10 I should also mention that this PyObject is different from the Python object type. A PyObject is the CPython implementation of the Python object that’s actually implemented using a C struct.

03:25 But because every type in Python inherits from object, then every type ends up mapping to a PyObject under the hood, whether it’s a string, an int, or something like your own type, defined with a class.

03:43 If I try to change the value of x, which, if you remember, is an immutable integer in Python, then what happens is a whole other PyObject is created in memory.

03:55 The name changes from referencing the first PyObject to this new one. The original PyObject remains in memory, but its reference count is now 0.

04:05 This tells the garbage collector that it can safely free the memory, or in other words, delete the original PyObject. If this were a mutable type, like a list, we wouldn’t see this PyObject duplication happen.

04:21 The value of that PyObject could be changed directly.

04:26 Let’s try setting a new name, y, to x. Instead of the value of x being copied to a new space in memory for y,

04:37 like with C, Python simply creates a new name and points it to the same PyObject

04:44 that x was referencing. As such, its reference count increases to 2. If I said something like y is x in the interactive shell, it would return True.

04:56 This is because the is operator checks to see if two names point to the same memory address, or the same PyObject. The integer type is still immutable, so changing y would still force Python to create a new PyObject to point y to.

05:17 Now, each PyObject only has one reference. The old PyObject containing the value 2337 can be freed from memory because no names reference it anymore.

05:33 The big idea is this: in Python, we don’t technically assign variables, even if that’s the terminology we often use. Instead, we bind names to spaces in memory called PyObjects. Modifying a mutable type will allow the value at that memory space to change, but modifying an immutable type will require a new space in memory, and then the name’s pointer will have to change so that it points to the new PyObject.

Jack on Dec. 9, 2020

Finally know how “is” works :)

Become a Member to join the conversation.