In Python, variables are created dynamically when you assign a value to them, there's no explicit declaration step. This flexibility means that trying to access a variable that hasn't been defined yet raises a NameError, which can crash your program unexpectedly.
Checking whether a variable exists before using it is a common need in scenarios like conditional initialization, dynamic code execution, configuration handling, and debugging. In this guide, you'll learn multiple reliable methods to check if a variable exists in Python, covering both local and global scopes.
Understanding the Problem
When you access a variable that hasn't been defined, Python raises a NameError:
print(username)Output:
NameError: name 'username' is not definedThe goal is to detect whether a variable exists before accessing it, so you can handle the missing case gracefully instead of letting your program crash.
Using a Try-Except Block
The most Pythonic way to check if a variable exists is to simply try accessing it and catch the NameError if it doesn't exist. This follows Python's EAFP (Easier to Ask Forgiveness than Permission) philosophy.
try:
username
print(f"Variable exists with value: {username}")
except NameError:
print("Variable 'username' does not exist.")Output:
Variable 'username' does not exist.Now, if the variable is defined:
username = "Alice"
try:
username
print(f"Variable exists with value: {username}")
except NameError:
print("Variable 'username' does not exist.")Output:
Variable exists with value: AliceUsing locals()
The locals() function returns a dictionary of all variables defined in the current local scope. You can check if a variable name exists as a key in this dictionary.
def greet():
name = "Alice"
if 'name' in locals():
print(f"Variable exists: name = {name}")
else:
print("Variable 'name' does not exist in local scope.")
greet()Output:
Variable exists: name = AliceThis method is particularly useful inside functions where you want to verify that a local variable has been assigned before using it.
Checking for a Variable That Doesn't Exist Locally
def greet():
if 'name' in locals():
print(f"name = {name}")
else:
print("Variable 'name' is not defined locally.")
greet()Output:
Variable 'name' is not defined locally.Using globals()
The globals() function returns a dictionary of all variables in the global (module-level) scope. Use it when you need to check for variables defined outside of functions and classes.
app_name = "MyApp"
def check_config():
if 'app_name' in globals():
print(f"Global variable found: app_name = {app_name}")
else:
print("Global variable 'app_name' is not defined.")
check_config()Output:
Global variable found: app_name = MyAppThis is especially useful when functions depend on global configuration variables that may or may not have been set:
def check_config():
if 'debug_mode' in globals():
print(f"Debug mode: {debug_mode}")
else:
print("'debug_mode' is not configured. Using default: False")
check_config()Output:
'debug_mode' is not configured. Using default: FalseCombining locals() and globals()
When you're unsure whether a variable lives in the local or global scope, check both:
threshold = 100 # Global variable
def process():
limit = 50 # Local variable
for var_name in ['limit', 'threshold', 'missing_var']:
if var_name in locals() or var_name in globals():
print(f"'{var_name}' exists.")
else:
print(f"'{var_name}' does NOT exist.")
process()Output:
'limit' exists.
'threshold' exists.
'missing_var' does NOT exist.Checking for Object Attributes with hasattr()
If you need to check whether an attribute exists on an object (rather than a standalone variable), use the built-in hasattr() function:
class User:
def __init__(self, name):
self.name = name
user = User("Alice")
print(hasattr(user, 'name')) # True
print(hasattr(user, 'email')) # FalseOutput:
True
FalseThis is commonly used when working with objects that might have optional attributes:
class Config:
def __init__(self):
self.host = "localhost"
config = Config()
if hasattr(config, 'port'):
print(f"Port: {config.port}")
else:
print("Port not configured. Using default: 8080")Output:
Port not configured. Using default: 8080Practical Example: Safe Variable Initialization
A common real-world pattern is initializing a variable only if it doesn't already exist. It is useful for counters, caches, or configuration defaults:
try:
counter
except NameError:
counter = 0
counter += 1
print(f"Counter: {counter}")Output (first run):
Counter: 1An alternative using globals():
if 'counter' not in globals():
counter = 0
counter += 1
print(f"Counter: {counter}")Quick Comparison of Methods
| Method | Scope | Best For | Pythonic |
|---|---|---|---|
try / except NameError |
Any scope | General-purpose checks | ✅ Most Pythonic |
'var' in locals() |
Local scope | Checking inside functions | ✅ Good |
'var' in globals() |
Global scope | Module-level variables | ✅ Good |
locals() + globals() |
Both scopes | When scope is uncertain | ✅ Good |
hasattr(obj, 'attr') |
Object attributes | Checking object/class/module attributes | ✅ Good |
Conclusion
Python provides several reliable ways to check if a variable exists:
try/except NameErroris the most Pythonic and versatile approach. It works regardless of scope and follows Python's EAFP philosophy.locals()andglobals()let you inspect specific scopes by checking if a variable name exists in their respective dictionaries.hasattr()is the right tool when checking for attributes on objects, classes, or modules.
For most situations, the try-except block is the cleanest choice. It keeps your code readable, handles edge cases naturally, and doesn't require you to think about which scope the variable belongs to.