Names, objects and references
In Python a variable is not a box that holds a value. It is a name in a namespace that refers to an object on the heap, and an object can have many names. Step through a seven-line program, refs.py, and watch the arrows: two names share one list, a change through one name shows through the other, == and is give different answers, and CPython frees the list the moment its last reference goes away.
5 quick questions
Pick an answer to see why. Your score saves with your progress.
01After a = [1, 2] and b = a and b.append(3), what does print(a) show?
b = a binds b to the same list object; nothing is copied. append changes that one object in place, so every name that refers to it sees [1, 2, 3].
02x = [1, 2, 3] and y = [1, 2, 3]. What are x == y and x is y?
Each list display builds a new object. The two lists have equal values, so == is True, but they are two different objects, so is is False.
03a and b refer to the same list. What does del a do?
del removes a name's binding from the namespace, not the object. The list's reference count drops by one, but b still refers to it, so it stays alive.
04In CPython, b holds the only reference to a list. Then the program runs b = None. When is the list freed?
CPython counts references. Rebinding b to None drops the list's count to 0, and CPython frees it straight away. The gc module is only needed for objects that refer to each other in a cycle.
05b = a, where a refers to a list. Which line moves only b to a new object and leaves a's list unchanged?
b + [4] builds a new list and = rebinds b to it. append, extend and += on a list all change the shared object in place, so a would see the 4 too.
Glossary
- Object
- A piece of data in memory with an identity, a type and a value. Every value in Python is an object.
- Name
- A label in a namespace that refers to one object. Assignment binds a name; it never copies the object.
- Namespace
- A table that maps names to objects. A module's global names live in a dict you can see with globals().
- Reference
- A pointer from a name (or a list slot, or an argument) to an object. Many references can point to one object.
- Alias
- One of two or more names that refer to the same object. A change made through one shows through the others.
- Mutable
- Able to change in place, like a list or a dict. Ints, strings and tuples are immutable: an operation makes a new object instead.
- Identity, id(), is
- Which object something is. id() gives a number unique to the object while it lives; is checks whether two references are the same object.
- Reference count
- CPython's count of the references to an object. When it falls to 0 the object is freed at once.
Notes and sources
- The counts in the figure count only this program's names. CPython's real reference count also includes every other reference, such as a slot in a list or a function's argument; sys.getrefcount() shows it, usually one higher than you expect because the call itself holds a reference.
- Freeing an object the moment its count reaches zero is a CPython implementation detail. Other implementations, such as PyPy, may free it later. Objects that refer to each other in a cycle never reach zero on their own; CPython's cycle collector (the gc module) finds them.
- None is one object shared by the whole program. Since Python 3.12 it is immortal (PEP 683): its reference count never changes, so the figure shows no count for it.
- id() is unique and constant for an object while it lives; in CPython it is the object's address in memory. After an object is freed, a new object may get the same id.
- For immutable values such as small ints and short strings, CPython may reuse one object, so is can give surprising answers. Compare values with ==, and keep is for identity, as in x is None.
- On macOS and Linux the command is often python3 rather than python; on Windows the py launcher also works. The $ is the terminal's own prompt.
- Python reference: Data model (objects, values and types)
- Python reference: Execution model (naming and binding)
- Python tutorial: Python scopes and namespaces
- Python reference: Assignment and the del statement
- Python reference: Expressions (list displays, is and ==)
- Python library: Built-in functions (id)
- Python/C API: Reference counting
- Python/C API: Memory management (the private heap)
- Python library: sys.getrefcount
- Python library: gc (the cycle collector)
- PEP 683: Immortal objects, using a fixed refcount
Quiz Unlocks after the last step.