Variables, Assignment and Constants in Python
A Python variable is a name bound to an object, not a box holding a value. That one distinction explains multiple assignment, swapping, dynamic typing and aliasing.
- Basics
- Data Types
- Operators
- Strings
- Control Flow
- Lists
- Tuples
- Sets
- Dictionaries
- Comprehensions
- Functions
- Advanced Functions
- Recursion
- Exception Handling
- File Handling
- Modules
- Standard Library
- OOP
- Advanced OOP
- Iterators and Generators
- Decorators
- Context Managers
- Descriptors and Dataclasses
- Python Internals
- Concurrency
- Regular Expressions
- Serialization
- Command Line Python
- Testing and Debugging
- Type Hints
- Performance
- Python Security
- DSA with Python
A variable is a label, not a box
In many languages a variable is a piece of memory of a fixed size, and assignment copies a value into it. Python does not work that way. In Python:
- Values are objects that live somewhere in memory.
- A variable is a name bound to an object.
- Assignment rebinds the name. It does not copy the object.
count = 10 # create the integer 10, bind the name count to it
count = 20 # bind count to a different object; 10 is untouched count ────────► 10 after line 1
count ────────► 20 after line 2
10 now unreferenced, and will be reclaimedEverything else in this note is a consequence of that picture.
Assignment
price = 249.50 # simple assignment
label = "invoice"
is_paid = FalseThere is no declaration step and no type to write. The name comes into existence at the moment it is first assigned. Using a name before assigning it is a NameError.
print(total) # NameError: name 'total' is not defined
total = 0Multiple and chained assignment
# Multiple assignment: pair the names with the values, position by position.
name, age, city = "Meera", 27, "Pune"
# Chained assignment: one object, three names bound to it.
x = y = z = 0
# Swapping, with no temporary variable.
a, b = 1, 2
a, b = b, a
print(a, b) # 2 1The swap works because the right hand side is fully evaluated before anything is assigned. Python builds the pair (2, 1) first, then unpacks it into a and b.
Chained assignment binds every name to the same object. With immutable values such as0that never matters. With a mutable value it matters a great deal:a = b = []gives two names for one list, and appending throughachanges whatbsees.
Unpacking with a star
first, *rest = [10, 20, 30, 40]
print(first) # 10
print(rest) # [20, 30, 40]
head, *middle, tail = [1, 2, 3, 4, 5]
print(middle) # [2, 3, 4]Dynamic typing
A name is not tied to a type. Rebinding it to a different kind of object is entirely legal.
value = 42
print(type(value)) # <class 'int'>
value = "forty two"
print(type(value)) # <class 'str'>Legal is not the same as advisable. Reusing one name for two different kinds of thing makes code hard to follow and defeats the type checkers covered later in this path. Rebind a name to a new value of the same kind; use a new name for a new kind of thing.
Dynamic but strong
print(2 + 3) # 5
print("2" + "3") # 23
print(2 + "3") # TypeError: unsupported operand type(s) for +: 'int' and 'str'Python will not guess what you meant. That refusal is what strongly typed means, and it is a feature: the error appears immediately instead of a wrong answer appearing much later.
Aliasing, and why it surprises people
first = [1, 2, 3]
second = first # not a copy; a second name for the same list
second.append(4)
print(first) # [1, 2, 3, 4]Nothing unusual happened. second = first bound a second name to one object, exactly as the label picture predicts. To get an independent list you must ask for one:
second = first.copy() # or list(first), or first[:]
second.append(5)
print(first) # unchangedThe same effect does not appear with numbers and strings, because those objects cannot be modified in place. Shallow and deep copying are covered fully in the internals notes later in this path.
Constants by convention
Python has no const keyword. Nothing prevents reassignment. The convention is to write a constant in capitals, which tells every reader that the value is not meant to change.
MAX_RETRIES = 3
TAX_RATE = 0.18
APP_NAME = "NoteHub"
MAX_RETRIES = 5 # Python permits this. A reviewer will not.Group constants at the top of the module. If a value appears twice in your code, or appears once but needs explaining, make it a named constant.
The del statement
temp = "scratch value"
del temp
# print(temp) # NameError: the name no longer existsdel removes the name, not necessarily the object. If another name still refers to the same object, that object stays alive.
Naming that earns its keep
| Weak | Better | Why |
|---|---|---|
d | days_overdue | A reader should not have to search for the meaning. |
list1 | invoices | Name the contents, not the container type. |
flag | is_verified | A boolean reads best as a yes or no question. |
tmp | previous_total | Temporary is a lifetime, not a description. |
l, O, I | anything else | Single letters that look like digits in most fonts. |
Common mistakes
- Reading a name before assigning it, and being surprised by
NameError. - Assuming
b = acopies a list or a dictionary. It does not. - Writing
a = b = []and later discovering both names change together. - Shadowing a built in:
list,str,dict,id,type,sum,maxandinputare all easy to overwrite by accident. - Expecting capitals to enforce immutability. They document intent only.
Best practices
- Assign a name close to where it is used, and give it the narrowest useful scope.
- Keep one name for one kind of thing throughout its life.
- Use multiple assignment when the values genuinely belong together, not to compress unrelated lines.
- Put constants at the top of the module in capitals, and refer to them everywhere instead of repeating literals.
Practice
- Draw the name to object diagram for
a = [1]; b = a; b.append(2)and predict whataprints. - Swap three variables so that
atakes b's value,btakes c's andctakes a's, in one statement. - Explain why
x = y = 5is harmless butx = y = {}deserves a second look. - Predict the output of
first, *rest = "python"and explain the result. - Assign
len = 5and then calllen("abc"). Explain the error and how to recover in the same session.
Conclusion
Assignment binds a name to an object; it never copies. Once that picture is fixed in your mind, multiple assignment, swapping, aliasing, dynamic typing and the whole later discussion of mutability follow from it without any further rules.