The global Keyword in Python 2026

Writing Functions Mar 16, 2026

The global Keyword in Python 2026

The global keyword allows a function to modify a variable defined in the global (module) scope. While powerful, it should be used sparingly. In 2026, modern Python code prefers cleaner alternatives whenever possible.

TL;DR — Key Takeaways 2026

  • global declares that a variable inside a function refers to the global scope
  • It is needed only when you want to assign to a global variable
  • Overusing global makes code harder to understand and test
  • Prefer returning values, using classes, or dependency injection instead

1. Basic Usage of global


counter = 0

def increment():
    global counter        # Declare we want to modify the global variable
    counter += 1
    return counter

print(increment())   # 1
print(increment())   # 2
print(counter)       # 2

2. Why global is Usually Not Recommended


# ❌ Bad practice - using global
count = 0

def bad_increment():
    global count
    count += 1

# ✅ Better approach - return value
def good_increment(current_count: int) -> int:
    return current_count + 1

# Even better - use a class
class Counter:
    def __init__(self):
        self.count = 0
    
    def increment(self):
        self.count += 1
        return self.count

3. Best Practices in 2026

  • Use global only when absolutely necessary (very rare in modern code)
  • Prefer returning values from functions instead of modifying globals
  • Use classes or modules with state when you need persistent data
  • Consider dependency injection or context managers for shared state
  • If you must use global, document it clearly with comments

How Python Decides a Name Is Global

Python decides the scope of a name when it compiles a function. If the function assigns to a name anywhere in its body, that name is local for the whole function, unless it is declared global or nonlocal. Reading a module variable without assigning to it needs no declaration.

This rule explains a common error. A function that first reads a module counter and then increments it raises UnboundLocalError, because the assignment makes the name local and the read happens before any local value exists.

The global statement fixes the error, but it also hides a dependency: anyone calling the function cannot see from its signature that it changes module state. Passing values in and returning results is usually clearer and easier to test.

Module-level constants that are read but never changed are fine. The problems come from functions that write to globals.

Worked Example: The Error, the Fix and the Better Design

We trigger UnboundLocalError, fix it with global, and then rewrite the code without global state.

counter = 0

def bump_broken():
    counter += 1          # assignment makes counter local

try:
    bump_broken()
except UnboundLocalError as e:
    print("Error:", e)

def bump_global():
    global counter
    counter += 1

bump_global(); bump_global()
print("global counter:", counter)

def bump(value: int) -> int:     # explicit input and output
    return value + 1

print("pure version:", bump(bump(0)))

The broken version raises UnboundLocalError because counter is treated as local. With global the module counter reaches 2. The pure version gives the same 2 without touching module state, so it can be tested in isolation.

Practical Tips

When you inherit code that uses global, refactor step by step. First pass the global value as a parameter, then return the new value, and finally remove the global statement once every caller uses the return value.

For true application settings, a single configuration object passed to functions, or a small settings module that is read but not changed, is easier to test than many global variables.

Search your code for the word global during reviews; each use deserves a short justification.

Common Mistakes

  • Expecting a read-then-assign to use the module value.
  • Using global to share data between many functions.
  • Declaring global for names that are only read.
  • Forgetting that tests share module state between runs.

Quick Summary

  • Any assignment makes a name local.
  • global lets a function rebind a module name.
  • Prefer parameters and return values.
  • Read-only module constants are fine.

Conclusion

The global keyword exists for a reason, but in 2026 it is considered a code smell in most situations. Professional Python developers avoid it by returning values, using classes, or applying better design patterns. Clean functions should not have hidden side effects on global state.

Next steps:

  • Search your codebase for global and refactor to use return values or classes

Related Tutorials

Share:
Last updated: March 2026
Built-in Functions in Python 2026 str() in Python 2026: String Conversion + Modern Formatting & Best Practices memoryview with JAX in Python 2026: Zero-Copy NumPy → JAX Array Interop + Efficient ML Examples memoryview with TensorFlow in Python 2026: Zero-Copy NumPy → Tensor Interop + GPU Pinning & ML Examples memoryview with TensorFlow in Python 2026: Zero-Copy NumPy → Tensor Interop + ML Examples memoryview with NumPy & PyTorch in Python 2026: Zero-Copy Views, Efficient Slicing & ML Interop Examples memoryview with NumPy in Python 2026: Zero-Copy Views, Efficient Slicing & Real ML Examples memoryview() in Python 2026: Zero-Copy Magic for Large Binary Data + Real Examples import() in Python 2026: How It Works, Security Risks & Modern Alternatives (importlib) zip() in Python 2026: How to Use It, strict=True Behavior & Real-World Examples vars() in Python 2026: Accessing Object Namespace + Modern Introspection Patterns type() in Python 2026: Dynamic Type Inspection & Object Creation + Modern Patterns tuple() in Python 2026: Immutable Sequences + Modern Patterns & Best Practices super() in Python 2026: Method Resolution & Modern Inheritance Patterns sum() in Python 2026: Summing Iterables + Modern Numeric Patterns & Best Practices staticmethod() in Python 2026: Static Methods, Utility Functions & Modern Best Practices sorted() in Python 2026: Sorting Iterables + Modern Patterns & Best Practices slice() in Python 2026: Creating Slice Objects + Modern Patterns & Best Practices setattr() in Python 2026: Dynamic Attribute Setting + Modern Patterns & Safety set() in Python 2026: Mutable Sets Creation + Modern Patterns & Best Practices