When you write a variable inside a Python function, that variable does not exist anywhere else in your program. It lives only inside that function. That rule is called local scope, and understanding it changes how you read and write Python code.
Python organises variables using a system of scopes. A scope defines which parts of your code can see a particular variable. Local scope is the narrowest and innermost level of that system. When Python encounters a name inside a function, the first place it looks is the local scope of that function. If the name is found there, Python uses it. If not, Python widens its search outward. Learning local scope early prevents a large category of bugs that trip up new programmers.
What Local Scope Means
Every time Python calls a function, it creates a fresh, private namespace just for that function call. A namespace is a container that maps names to values. Any variable you assign inside the function body goes into that namespace. The variable is said to be local to the function.
When the function finishes and returns, Python throws away that namespace. The local variables inside it cease to exist. The next time you call the same function, a brand-new namespace is created, completely empty again. Local variables do not carry over between calls.
def greet():
message = "Hello, world!" # 'message' is a local variable
print(message)
greet() # prints: Hello, world!
print(message) # NameError: name 'message' is not defined
The variable message is created inside greet(), so it belongs to that function's local scope. The call to print(message) on the last line runs in the global scope, where message has never been defined. Python cannot find it, so it raises a NameError.
Python decides that a variable is local at compile time, not at runtime. If any assignment to a name appears anywhere in a function body, Python treats that name as local throughout the entire function — even on lines before the assignment runs.
The LEGB Rule
Python resolves variable names by searching scopes in a specific order, which programmers call the LEGB rule: Local, Enclosing, Global, Built-in. Python checks local scope first. Only if no match is found there does it move outward to the next layer. Local scope always wins over a global variable with the same name, which is why local variables can shadow globals without affecting them.
Build a function that creates a local variable called count set to 10 and prints it. Click each token in the correct order:
def, then the function name, then empty parentheses () and a colon :. Inside the function body, count = 10 creates a local variable, and print(count) displays it. The distractors return and global are not needed here — return sends a value back to the caller, and global declares a global variable, neither of which is part of this task.
Local Variables and Parameters
There are two ways a variable becomes local to a function. The first way is through assignment: any line inside a function that assigns a value to a name makes that name local. The second way is through parameters: when you define a function with parameters, those parameter names are automatically local for every call.
def add_tax(price): # 'price' is a local parameter
tax_rate = 0.08 # 'tax_rate' is a local variable
total = price * (1 + tax_rate) # 'total' is a local variable
return total
result = add_tax(50)
print(result) # 54.0
# This would raise NameError:
# print(price) # 'price' does not exist outside add_tax
All three names — price, tax_rate, and total — are local to add_tax(). None of them exist once the function has returned. The value computed by total is preserved because it was returned and assigned to result, which lives in the global scope.
If another part of your program needs the result of a local calculation, always use return to pass the value out of the function. Relying on a global variable to carry information out of a function makes code harder to test and reason about.
The UnboundLocalError
New Python programmers frequently encounter UnboundLocalError. It happens when Python sees that a variable is local (because an assignment to it appears somewhere in the function) but the code tries to read it before that assignment has executed. Python marks the variable as local at compile time, so it cannot fall back to the global version.
score = 100 # global variable
def update_score():
print(score) # UnboundLocalError here
score = score + 10 # assignment makes 'score' local
update_score()
Because score = score + 10 appears in the function, Python treats score as local throughout update_score(). When print(score) runs first, Python looks for a local score that has not been assigned yet — and raises UnboundLocalError. The fix is to either pass score as a parameter or use a completely new local name for the updated value.
This function is supposed to calculate a discounted price. One line causes an UnboundLocalError. Click the line you think is wrong, then hit check.
original, so Python treats it as local throughout the entire function. Line 3 tries to print original before that assignment has run, raising UnboundLocalError. To fix this, pass original as a parameter: def apply_discount(original): and call apply_discount(80). Now original is a parameter (still local) and the print on line 3 works correctly.
Local Scope vs. Global Scope
Global scope refers to variables defined at the top level of a module — outside any function or class. These variables are visible everywhere in the module. Local variables, by contrast, are visible only inside the function where they were created. The two scopes are completely independent, even when they use the same name.
name = "Global Alice" # global variable
def introduce():
name = "Local Bob" # local variable — shadows the global
print(name) # prints: Local Bob
introduce()
print(name) # prints: Global Alice (unchanged)
Inside introduce(), the assignment name = "Local Bob" creates a local variable that shadows the global name. The global value is never touched. After the function returns, the global name is still "Global Alice". This is one of the key benefits of local scope: functions cannot accidentally overwrite data they were not meant to modify.
Avoid using the global keyword to modify global variables from inside a function. While Python allows it, the practice creates hidden dependencies between functions and the global state, making code difficult to test and debug. Prefer passing values as arguments and returning results.
- Local
- Inside a function body or as a function parameter
- Global
- At the top level of a module, outside any function
- Local
- Only inside the function where it was created
- Global
- Anywhere in the module — including inside functions (read-only without
global)
- Local
- Only for the duration of a single function call; destroyed when the function returns
- Global
- For the entire lifetime of the program, or until explicitly deleted with
del
- Local
- Yes. Each function has its own local namespace. A variable named
resultin function A and a variable namedresultin function B are completely independent. - Global
- There is only one global namespace per module, so global variable names must be unique within a module.
"A name that is bound in a block is local to that block." — Python Language Reference
How to Use Local Scope Correctly in Python
Following these four steps will help you write functions that are clean, predictable, and free from scope-related bugs.
-
Define the function and declare variables inside it
Create a function using the
defkeyword. Any variable you assign inside the function body is automatically local — you do not need any special keyword. Keep variable declarations close to where they are first used to make the local scope obvious to readers. -
Access local variables only within the same function
Read and use local variables freely inside the function where they were created. Never try to access them from outside the function — Python will raise a
NameErrorif you attempt to read a local variable from the global scope or from another function. -
Return values when other code needs the result
If code outside the function needs the result of a local calculation, use a
returnstatement and capture the returned value in a new variable at the calling scope. This is the clean, explicit way to pass information out of a function without exposing its internal variables. -
Avoid referencing a local variable before assigning it
Always assign a value to a local variable before trying to read it in the same function. If Python sees an assignment to a name anywhere in the function, it marks that name as local throughout the entire function. Reading it before the assignment executes raises an
UnboundLocalError.
Python Learning Summary Points
- A variable is local to a function whenever an assignment to that name appears anywhere inside the function body. Python determines this at compile time, not at runtime.
- Function parameters are automatically local variables. They are created when the function is called and destroyed when the function returns.
- Local variables cannot be read from outside their function. Attempting to do so raises a
NameError. To share a result, usereturn. - Two functions can each have a local variable with the same name. They do not interfere with each other because each function call creates its own local namespace.
- Python resolves names using the LEGB rule — Local, Enclosing, Global, Built-in — always checking local scope first.
- Reading a local variable before it has been assigned in the same function raises
UnboundLocalError, a specific form of scope error that often surprises beginners.
Local scope is one of the rules that makes Python functions reliable and reusable. Because local variables are private to each function call, functions do not interfere with each other's data. That isolation is a feature, not a limitation. When you write a function that keeps its working variables local and communicates through parameters and return values, you build code that is far easier to test, read, and extend.
Frequently Asked Questions
Local scope in Python refers to the region of code inside a function where a variable is created and only accessible. A locally scoped variable exists only for the lifetime of that function call and cannot be read or modified from outside the function.
A local variable is any variable created by an assignment statement inside a function body. Python automatically treats it as local to that function, meaning it is created when the function runs and destroyed when the function returns.
The LEGB rule describes the order Python uses to look up a variable name: Local, Enclosing, Global, and Built-in. Python checks local scope first, which is why a local variable with the same name as a global variable takes priority inside a function.
Python raises NameError when code tries to access a variable that has not yet been assigned in the current scope. If you try to read a local variable before assigning a value to it inside the same function, Python cannot find it and raises NameError.
Yes. A local variable can share a name with a global variable. Inside the function, Python will use the local version. Outside the function, the global version remains unchanged. The two are completely independent.
Yes. Parameters defined in a function signature are treated as local variables for that function. They are created when the function is called with arguments and destroyed when the function returns.
When a function returns, its local namespace is destroyed. All local variables cease to exist. Their values are not retained between calls unless they are returned from the function and assigned to another variable.
Global scope refers to variables defined at the top level of a module, outside any function. Local scope refers to variables defined inside a function. Global variables are accessible throughout the module, while local variables are accessible only within the function where they were created.
UnboundLocalError is raised when Python detects that a variable is local to a function (because it appears on the left side of an assignment somewhere in the function) but the code tries to read it before that assignment has executed.