Guide Python Intermediate

6.12 Common Mistakes

The most common variable and memory-related bugs in Python — UnboundLocalError, shared mutable objects, variable shadowing, and assuming Python has block scope.

3 min read

UnboundLocalError

What Goes Wrong?

Referencing a variable inside a function before assigning it, when that same name is also assigned somewhere later in that same function — Python decides the name is local to the whole function (because it’s assigned there), so the earlier read fails.

count = 5

def broken():
    print(count)     # Python sees the later assignment below and treats count as LOCAL here
    count = 1

>>> broken()
Traceback (most recent call last):
UnboundLocalError: cannot access local variable 'count' where it is not associated with a value

The fix is the global keyword covered in 6.8 Variable Scope.

Shared Mutable Objects

Forgetting that b = a shares the same object (see 6.2 Objects and Variable References), then being surprised when mutating b also changes a. The mutable-default-argument variant of this bug — a default argument evaluated once, at function-definition time, and shared across every call — is one of the most common real-world instances of this pattern.

Variable Shadowing

What Is It?

A local variable (or function parameter) using the same name as a global variable or built-in function, silently hiding it within that scope.

list = [1, 2, 3]      # shadows the built-in list() constructor!
>>> list("abc")        # this now fails -- 'list' is a variable, not the builtin
Traceback (most recent call last):
TypeError: 'list' object is not callable

Incorrect Scope

What Goes Wrong?

Assuming a variable assigned inside an if or for block is scoped to just that block — Python has no block scope, only function scope, so it actually leaks into the surrounding function or module.

if True:
    x = 10             # NOT block-scoped -- this leaks into the enclosing scope

>>> print(x)             # accessible here, unlike in C/Java
10

Quick Interview Answer

“The recurring variable-related bugs are: UnboundLocalError, from reading a name before an assignment further down in the same function makes Python treat it as local; shared mutable objects, from forgetting b = a shares one object rather than copying it; variable shadowing, from naming a local the same as a builtin like list; and assuming block scope exists for if/for, when Python only has function scope, so a variable assigned inside a loop or conditional leaks into the surrounding function.”

Common Mistakes

  • Fixing an UnboundLocalError by renaming the variable instead of understanding why it happened — the real fix is usually global, or restructuring so the read doesn’t precede the write.
  • Naming a variable list, dict, str, type, or id — all shadow built-ins and cause confusing failures much later in the same scope.
  • Relying on a loop variable’s final value after the loop ends — it works because there’s no block scope, but it’s fragile if the loop body is later restructured.

Add More Questions to This Guide

Know a question that should be here? Share it and help the community!

Open Google Form