How it works
A name refers to an object within a scope. In ordinary function code, lookup searches local names, enclosing function scopes, the module namespace and built-ins. A local assignment normally creates a local binding rather than changing a module name.
Python determines local names for a function block from its bindings. Reading a local name before its value has been assigned raises UnboundLocalError, even when a module-level name with the same spelling exists.
Choices and common mistakes
Prefer explicit parameters and return values when passing information between functions. It makes data dependencies easier to follow.
A for or if block does not create a separate ordinary local scope. Comprehensions have their own scope in Python 3, so do not assume every indented construct behaves alike.
Try it yourself
Make a function return a locally formatted name while preserving the module-level original. Explain the distinction between rebinding a name and modifying a mutable object.
Syntax
label = "module"
def show():
label = "local"
return labelExamples
Keep a local label
Show that a function can use the same name independently.
label = "module"
def show():
label = "local"
return label
print(show())
print(label)- The assignment inside show binds a local name. Returning it gives the caller the string local.
- The final print runs at module level, where label still refers to module. Returning a value does not rebind the caller’s names.
- Use local names for intermediate calculations that should not affect other operations.
- Expected output: local module
Read an enclosing value
Let a nested function use information from its creator.
def make_label(prefix):
def label(name):
return prefix + ": " + name
return label
task_label = make_label("Task")
print(task_label("Read"))- label can read prefix from the enclosing make_label call. Returning the nested function retains access to that binding.
- Calling task_label supplies name while prefix remains the captured value. No global variable is needed.
- This is useful for a small configured callback; see closures for lifetime and late-binding details.
- Expected output: Task: Read
Recognise a local-before-assignment error
Understand why a read does not fall back to a module variable.
count = 10
def broken():
print(count)
count = 1
try:
broken()
except UnboundLocalError:
print("Local count has no value yet")- The assignment anywhere in broken makes count local throughout that function. The earlier print therefore reads an unassigned local.
- The handler reports the problem; it does not make the function correct. Passing count as an argument is often the clearer fix.
- Use this explanation when diagnosing an UnboundLocalError rather than adding global automatically.
- Expected output: Local count has no value yet
Best practices
- Prefer explicit parameters and return values when passing information between functions. It makes data dependencies easier to follow.
- A for or if block does not create a separate ordinary local scope. Comprehensions have their own scope in Python 3, so do not assume every indented construct behaves alike.
Runtime & versions
Python interpreter. Feature availability depends on the language and runtime version used by your project; consult the official reference below.
Python language reference