Skip to main content

How to Check if a Variable Exists in Python

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 defined

The 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: Alice
tip

The try-except approach is the recommended method in most situations. It's clean, handles edge cases naturally, and doesn't require you to know whether the variable is local or global.

Using 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 = Alice

This 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 = MyApp

This 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: False

Combining 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')) # False

Output:

True
False

This 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: 8080
Don't Confuse Variables with Attributes
  • Use locals() / globals() / try-except for standalone variables.
  • Use hasattr() for attributes on objects, classes, or modules.
import math

# Checking a module attribute
print(hasattr(math, 'pi')) # True
print(hasattr(math, 'tau')) # True
print(hasattr(math, 'golden')) # False

Practical 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:

# Initialize 'counter' only if it hasn't been set
try:
counter
except NameError:
counter = 0

counter += 1
print(f"Counter: {counter}")

Output (first run):

Counter: 1

An alternative using globals():

if 'counter' not in globals():
counter = 0

counter += 1
print(f"Counter: {counter}")

Quick Comparison of Methods

MethodScopeBest ForPythonic
try / except NameErrorAny scopeGeneral-purpose checks✅ Most Pythonic
'var' in locals()Local scopeChecking inside functions✅ Good
'var' in globals()Global scopeModule-level variables✅ Good
locals() + globals()Both scopesWhen scope is uncertain✅ Good
hasattr(obj, 'attr')Object attributesChecking object/class/module attributes✅ Good

Conclusion

Python provides several reliable ways to check if a variable exists:

  • try / except NameError is the most Pythonic and versatile approach. It works regardless of scope and follows Python's EAFP philosophy.
  • locals() and globals() 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.