


The Case Against the `global` Keyword: Strategies for Cleaner Code
Jul 25, 2025 am 11:36 AMAvoid using the global keyword unnecessarily as it leads to code that is harder to test, debug, and maintain; instead, use function parameters and return values to pass data explicitly. 2. Replace global variables with pure functions that depend only on their inputs and produce outputs without side effects, improving predictability and testability. 3. Use classes to encapsulate and manage shared state when multiple functions need to modify related data, enabling reusability and avoiding global namespace pollution. 4. Leverage closures for maintaining private, controlled state across function calls without relying on global or class-based state. 5. Reserve global for rare cases like simple scripts or temporary module-level patches, but always consider whether the same can be achieved through parameter passing, return values, or encapsulation. 6. Treat global like a spare tire—useful in emergencies but unsuitable for regular use, as avoiding it promotes cleaner, more modular, and maintainable code design.
You don’t need the global
keyword as often as you might think—and overusing it is a sign your code could be more readable, testable, and maintainable. While global
has its place in Python, reaching for it too quickly often leads to tangled, hard-to-follow logic. Here’s how to write cleaner code by avoiding unnecessary global state.

Why global
Is a Code Smell
The global
keyword lets you modify a variable defined in the global scope from within a function. But when you use it, you’re tightly coupling that function to external state. That makes your code:
- Harder to test (you need to manage global state between tests)
- Difficult to reason about (who changed what, and when?)
- Prone to bugs in concurrent or recursive contexts
- Less reusable (the function won’t work without specific global variables)
Instead of modifying global variables, aim for pure functions—functions that depend only on their inputs and return a value without side effects.

Replace Global Variables with Function Parameters and Returns
One of the simplest and most effective strategies is to pass data in and return results explicitly.
Instead of this:

counter = 0 def increment(): global counter counter = 1
Do this:
def increment(counter): return counter 1 # Usage counter = 0 counter = increment(counter)
Now the function is self-contained, predictable, and easy to test:
assert increment(5) == 6
If you’re managing more complex state, consider returning multiple values or using a dictionary or dataclass:
def process_user(data, score): return {**data, 'processed': True}, score 10
Use Classes to Manage Shared State
When you genuinely need to maintain and modify state across multiple function calls, a class is usually a better fit than global variables.
Instead of:
user_name = "" login_status = False def login(name): global user_name, login_status user_name = name login_status = True
Use a class:
class UserSession: def __init__(self): self.user_name = "" self.login_status = False def login(self, name): self.user_name = name self.login_status = True # Usage session = UserSession() session.login("Alice")
This approach encapsulates state, avoids global pollution, and makes it easy to have multiple independent instances.
Leverage Closures for Controlled State Access
Sometimes you want to hide state but still avoid globals. Closures let you encapsulate data within a nested function scope.
def create_counter(): count = 0 def increment(): nonlocal count count = 1 return count return increment # Usage counter = create_counter() print(counter()) # 1 print(counter()) # 2
Here, count
is not global, not part of a class, but still maintains state across calls—without global
. It’s private, reusable, and thread-safe (as long as you don’t share the closure).
When Is global
Acceptable?
There are rare cases where global
makes sense:
- Patching module-level constants during testing (though monkeypatching tools are better)
- Simple scripts or prototypes where clarity isn’t critical
- Singletons or configuration flags (but consider using a config object instead)
Even then, ask: Can I pass it in? Can I return it? Can I encapsulate it?
Bottom Line
Avoiding global
pushes you toward better design: smaller functions, clearer dependencies, and more modular code. You’ll write fewer bugs and make your code easier to test and reuse.
Refactor global dependencies into parameters, return values, classes, or closures. The extra few lines of code are worth the long-term clarity.
Basically, treat global
like a spare tire—useful in a pinch, but not for everyday driving.
The above is the detailed content of The Case Against the `global` Keyword: Strategies for Cleaner Code. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undress AI Tool
Undress images for free

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

Passbyvaluemeansacopyofthedataispassed,sochangesinsidethefunctiondonotaffecttheoriginalvariable,asseeninCwithprimitivesorPythonwithimmutabletypes.2.Passbyreferencemeansthefunctionreceivesadirectreferencetotheoriginal,somodificationsinsidethefunctiona

APHPvariable'slifecyclebeginswithmemoryallocationviazvalcreation,whichstoresthevalue,type,referencecount,andreferenceflag.2.Whenvariablesareassignedorshared,PHPusesreferencecountingandcopy-on-writetooptimizememoryusage,onlyduplicatingdatawhennecessar

Avoidusingtheglobalkeywordunnecessarilyasitleadstocodethatishardertotest,debug,andmaintain;instead,usefunctionparametersandreturnvaluestopassdataexplicitly.2.Replaceglobalvariableswithpurefunctionsthatdependonlyontheirinputsandproduceoutputswithoutsi

TypedpropertiesinPHP7.4 allowdirecttypedeclarationforclassproperties,improvingreliability,IDEsupport,andcodeclarity;2.Theyenforcetypesafety,reducebugs,enablebetterautocompletion,andminimizeconstructorchecks;3.Tomigrate,useexisting@vardocblockstoaddty

Variable variables use the value of one variable as the name of another variable through the $$var syntax; 2. For example, when $myVar is "hello", $$myVar is equivalent to $hello and can be assigned a value; 3. In practical applications, it can be used to dynamically process form data, such as traversing $_POST with foreach and creating corresponding variables with $$key; 4. There are problems such as poor readability, high security risks, and disrupting static analysis, especially avoiding the use of $$ for user input; 5. It is recommended to use arrays or objects instead of creating dynamic variables, such as storing data into $data array instead of creating dynamic variables; 6. Using ${$var} curly brace syntax can improve code clarity, especially in complex scenarios. Variable change

PHPsuperglobalsinclude$_GET,$_POST,$_REQUEST,$_SESSION,$_COOKIE,$_SERVER,$_FILES,$_ENV,and$GLOBALS,eachservingdistinctpurposesbeyondjusthandlingformdata;theyenablestatemanagement,serverinteraction,andenvironmentaccess.1.$_REQUESTcombines$_GET,$_POST,

Constantscannotbechangedafterdefinition,whilevariablescan;1.Variablesstartwith$,aremutable,scoped,andidealfordynamicdata;2.Constantsusedefine()orconst,haveno$,areimmutable,globallyscoped,andbestforfixedvalueslikeconfiguration;3.Useconstantsforunchang

isset()checksifavariableisdeclaredandnotnull,returningtrueforemptystrings,0,'0',false,andemptyarrays;useittoconfirmavariableexistsandhasbeenset,suchasverifyingforminputslike$_POST['email'].2.empty()determinesifavalueis"empty"inauser-logicse
