How to Use a Global Variable Inside a Python Function
Python variables follow scope rules that determine where a name can be read or assigned. A module-level variable can be read inside a function, but assigning to that same name requires special handling.
Reading a Global Variable
A function can read a module-level variable without the global keyword:
app_name = "Nalar"
def print_app_name():
print(app_name)
print_app_name()Because the function does not assign to app_name, Python resolves the name from the enclosing module scope.
Modifying a Global Variable
When a function assigns to a name, Python normally treats that name as local to the function. Use global when you intentionally want to rebind the module-level variable:
counter = 0
def increment_counter():
global counter
counter += 1
increment_counter()
print(counter) # 1Without global counter, the augmented assignment would try to read a local counter before it had been assigned, raising UnboundLocalError.
Global Mutable Objects
Mutating an existing global object is different from rebinding the variable itself:
settings = {"debug": False}
def enable_debug():
settings["debug"] = TrueThis does not need global because the function is modifying the dictionary object rather than assigning a new object to the name settings.
Rebinding the name does require it:
settings = {"debug": False}
def reset_settings():
global settings
settings = {"debug": False}Prefer Returning Values When Possible
Global state can make functions harder to test and reason about. Often a return value is simpler:
def increment_counter(counter):
return counter + 1
counter = 0
counter = increment_counter(counter)For larger applications, state can also live in a class, configuration object, dependency container, or another explicit data structure.
global vs nonlocal
Use global for names in the module scope. Use nonlocal for names in an enclosing function scope:
def make_counter():
count = 0
def increment():
nonlocal count
count += 1
return count
return incrementConclusion
Use global only when a function genuinely needs to rebind a module-level name. Reading global values does not require it, and mutating a referenced object is not the same as rebinding the variable. For maintainable code, prefer explicit inputs and return values whenever practical.