Variables and names

Beginner25 min

Understand that a Python variable is a name bound to an object, and use assignment, swapping and constants correctly.

What you will learn
  • Explain assignment as binding a name to an object
  • Use multiple assignment and swap two names
  • Remove a name with del, and avoid shadowing built-in names
On this page

In many languages a variable is a labelled box that holds a value. In Python it is closer to a name tag that you stick on an object. That difference explains several behaviours that otherwise look odd.

The fundamentals lesson on variables covers assignment and scope in general. Here we focus on how Python does it.

Assignment binds a name

name = value does not copy the value into a box. It makes name refer to the value, and a later assignment simply moves the tag.

rebinding.py
count = 10
count = count + 1
print(count)
Output
11

count = count + 1 first works out the right side (11), then binds the name count to that new value. The old 10 is simply no longer tagged.

You can bind several names in one statement:

multiple_assignment.py
x = y = 0
width, height = 4, 5
print(x, y, width, height)
Output
0 0 4 5

x = y = 0 binds two names to the same value. width, height = 4, 5 binds two names at once, one for each value on the right.

That second form gives Python its neat way to swap two names without a temporary variable. The right side is worked out first, then the names are bound:

swap.py
width, height = 4, 5
width, height = height, width
print(width, height)
Output
5 4

The pair of values on each side is called a tuple. Lesson 20 covers tuples properly, and for now it is enough to know that this one-line swap works.

Names and objects

Two names can refer to the same object. The is operator asks whether two names refer to the exact same object, which is a stricter question than whether they have equal values.

names_and_objects.py
first = "spam"
second = first
print(first is second)
second = second + "!"
print(first, second)
print(first is second)
Output
True
spam spam!
False

After second = first the answer is True: one object, two names. The line second = second + "!" creates a new string and moves the second tag to it, so first keeps the original.

Strings and numbers cannot be changed after they are made, so sharing them is harmless. Lists can be changed, and there a shared name shows up as a surprise. Lesson 19 teaches lists. For now, read the square brackets in this preview as “a collection of three numbers”, and append as “add one to the end”:

shared_list.py
a = [1, 2, 3]
b = a
b.append(4)
print(a)
print(a is b)
Output
[1, 2, 3, 4]
True

b = a does not copy the list. Both names point at the same one, so growing it through b changes what a sees. If you keep one rule from this lesson, keep this one: assignment never copies an object. The lists lesson shows how to make a real copy.

Choosing names

A name may contain letters, digits and underscores, cannot start with a digit, and is case-sensitive, so Total and total are different. Names must not be Python’s reserved words such as if, for or class.

Python has no constants. MAX_RETRIES = 3 is only a convention: capital letters tell readers not to reassign it, and nothing stops you if you do.

A few names, such as match, case, type and lazy Requires version 3.15 or later, are soft keywords. They have special meaning only in specific places, so you can still use them as ordinary variable names, though it is usually clearer not to.

Removing a name

del name removes a name, so using it afterwards is an error. You will rarely need it, but it helps to see what happens when a name hides something else, as in the next section.

Shadowing built-ins

The most damaging naming mistake is shadowing a built-in. Names like int, str, print and input are built-in functions. If you assign to one, your variable hides the function.

shadowing.py
print(int("42"))
int = 5
print(int)
del int
print(int("42"))
Output
42
5
42

After int = 5, calling int("42") would raise TypeError: 'int' object is not callable. Here del int removes our variable, and the built-in becomes visible again. In real code, simply pick a different name such as count.

Common pitfalls

  • Using a name before it exists. print(total) before any total = ... raises NameError.
  • Typos create new names. Writing conut = count + 1 quietly binds a new name. Editors and linters catch many of these.
  • Believing b = a copies. See the list example above.
  • Reusing a built-in’s name such as list, max or sum for your own variable. Pick a more specific name.
ExerciseTrace the bindings

Without running it, work out what the last line prints. Then run it and compare. Input: none. Expected output: one line.

trace_bindings.py
a = 5
b = a
a = a + 1
c = b
b, c = c + 10, a
a = "five"
d = a
d = d + "!"
print(a, b, c, d)
Show solution
five 15 6 five!

Step by step: a and b are 5. Then a becomes 6, and c takes b’s value, 5. The pair assignment evaluates the right side first, giving (15, 6), so b is 15 and c is 6. Finally a is rebound to "five", d gets the same string, and d + "!" creates a new one.

ExerciseSwap and predict

Predict the output, then run it. Input: none. Expected output: one line with three words.

swap_predict.py
a = "left"
b = "right"
a, b = b, a
c = a
a = "centre"
print(a, b, c)
Show solution
centre left right

After the swap, a is "right" and b is "left". Then c is tagged onto the same "right" string, and a moves on to "centre". Moving a does not touch c.

ExerciseFix the shadowing bug

This program is meant to print 5 43, but it crashes. Rename the variable so the program works.

int = 5
print(int, int("42") + 1)
Output
TypeError: 'int' object is not callable
Show solution
shadow_fixed.py
count = 5
print(count, int("42") + 1)
Output
5 43

The variable no longer hides the built-in int, so int("42") converts the text again.

Summary

  • A Python variable is a name bound to an object. Assignment never copies.
  • a, b = b, a swaps two names. is tests whether two names share one object, and del removes a name.
  • Constants are a naming convention. Avoid names that shadow built-ins.

That completes the first module. The next module covers numbers and text in depth.