Back to Blog
Python

Python Local vs Global Variable: Scope Explained

python local vs global variable: Understand the difference between local and global variables in Python, how scope resolution works, and when to use each.

PythonVariable ScopeGlobal VariablesLEGB RuleNonlocal Keyword
Illustration contrasting a local variable inside a function with a global variable at module level in Python

python local vs global variable requires a clear understanding of the core syntax, runtime behavior, and practical implementation patterns demonstrated in the examples below.

When you write x = 5 inside a function, Python treats it differently than x = 5 at the top level of a module. The distinction between local and global variables determines where a name is visible and how assignment behaves. Misunderstanding this can lead to UnboundLocalError, unexpected side effects, or code that silently uses the wrong value. This article explains the mechanics of Python variable scope and gives you practical rules for using local and global variables correctly.

How Python Resolves Names: The LEGB Rule

Python uses the LEGB rule to look up a name: Local, Enclosing, Global, Built-in. When you reference a variable, Python searches in that order. The first place it finds a definition wins.

  • Local: names assigned inside the current function.
  • Enclosing: names in the enclosing function (for nested functions).
  • Global: names assigned at the module level.
  • Built-in: names pre-defined in Python's builtins module.

This rule explains why a variable defined at module level is visible inside a function when you only read it. For example:

count = 10 def show_count(): print(count) show_count() # prints 10

Because count is not assigned inside show_count, Python looks up the enclosing scope, finds no local definition, then finds count in the global scope. The read works without any special keyword.

Assignment Creates a Local Variable by Default

When you assign a value to a name inside a function, Python creates a local variable unless you explicitly declare otherwise. This is the most common source of confusion. Consider:

count = 10 def increment(): count = count + 1 increment()

This code raises UnboundLocalError: local variable 'count' referenced before assignment. The reason is that the assignment count = count + 1 makes count local to increment. Python sees the assignment and decides that count is local for the entire function, so the reference on the right-hand side looks for a local count that hasn't been defined yet.

To modify a global variable inside a function, you must use the global keyword:

count = 10 def increment(): global count count = count + 1 increment() print(count) # prints 11

The global statement tells Python that count refers to the module-level variable. Without it, assignment always creates a new local variable.

The global Keyword: When and Why to Use It

The global keyword is necessary only when you want to assign a new value to a global name from inside a function. Reading a global variable does not require global. You can also mutate a global object (like a list or dictionary) without global, because you are not rebinding the name:

items = [] def add_item(item): items.append(item) # no global needed add_item('apple') print(items) # ['apple']

Here items.append modifies the existing list, not the variable binding. If you tried items = items + [item], you would need global because that rebinds items.

Using global excessively can make code harder to reason about. Every function that modifies a global variable becomes coupled to that variable's lifetime and state. In larger programs, this often leads to subtle bugs when multiple functions modify the same global in different orders.

The nonlocal Keyword for Nested Functions

Nested functions have an intermediate scope between local and global: the enclosing function's scope. The nonlocal keyword lets you assign to a variable in that enclosing scope. Without it, assignment inside a nested function creates a local variable, just like in the top-level case.

def outer(): count = 0 def inner(): nonlocal count count += 1 inner() inner() print(count) # prints 2 outer()

If you omit nonlocal, the count += 1 inside inner raises UnboundLocalError for the same reason as before. nonlocal is essential for closures that need to maintain state without resorting to mutable containers or global variables.

Common Mistakes and Their Consequences

One frequent mistake is assuming that a global variable can be reassigned inside a function without a declaration. This produces the UnboundLocalError shown earlier. Another mistake is using global when you only need to read a value. That is unnecessary but not harmful, though it can mislead readers into thinking the function modifies the global.

A subtler issue arises when a global variable is shadowed by a local variable with the same name. This can hide a bug where you meant to use the global but accidentally created a local. For example:

config = {'debug': True} def check(): config = {'debug': False} # local, not the global if config['debug']: print('debug on')

The function uses a local config, leaving the global untouched. This is often unintended. Naming local variables differently from globals can prevent this confusion.

Performance and Maintainability Considerations

Local variable access is faster than global access in CPython because local names are stored in a fast array and looked up by index, while global names require a dictionary lookup. In tight loops, this difference can matter. However, for most application code, the readability and correctness of scope management outweigh micro-optimizations. If you need to use a global value frequently inside a loop, assign it to a local variable first:

# Instead of referencing the global many times # do this: threshold = MAX_THRESHOLD for item in data: if item > threshold: ...

This also makes the code more self-contained and easier to test.

From a maintainability perspective, global variables create hidden dependencies. A function that reads a global is not pure; its behavior depends on external state. This complicates unit testing and debugging. Prefer passing values as arguments and returning results. Use globals for constants that never change, or for genuinely shared state like a configuration object that is intentionally global.

Choosing Between Local and Global Variables

The decision is not about which is better in the abstract; it is about what fits the situation. Use local variables for intermediate calculations, loop counters, and any value that belongs to a function's operation. Use global variables for constants that are used across many functions, or for a small set of well-known shared state that is deliberately visible module-wide.

If you find yourself using global in many functions, consider whether the state should be encapsulated in a class or passed explicitly. For example, instead of:

counter = 0 def inc(): global counter counter += 1

You could write a small class or use a mutable object like a list to avoid global:

counter = [0] def inc(): counter[0] += 1

The list approach avoids the global keyword but is not necessarily clearer. The real fix is to think about the data flow. If the counter is part of a larger system, a class with instance state is usually more maintainable.

Scope in Modules and Imports

When you import a module, its global variables become attributes of the module object. If you do from module import var, you create a local binding in the importing module; reassigning that local does not change the original module variable. If you do import module and then module.var = new_value, you modify the module's global. This distinction is important when sharing state across modules. Prefer import module and access via module.var to make the origin explicit.

Understanding the difference between local and global variables in Python is not just about avoiding errors. It is about writing code that communicates its data flow clearly. Prefer local variables for function-specific work, use globals sparingly for true constants or intentional shared state, and use global and nonlocal only when you actually need to rebind a name in an outer scope. This keeps your functions predictable and your program easier to reason about.

python local vs global variable: Practical Usage and Code Ex | RYUSLOG DEV