dir() in Python 2026: Introspection & Object Attribute Listing + Modern Use Cases
The built-in dir() function returns a sorted list of valid attribute names for an object — the most basic and powerful introspection tool in Python. In 2026 it remains indispensable for debugging, REPL exploration, dynamic attribute access, metaprogramming, testing, and IDE-like functionality in scripts or notebooks.
With Python 3.12–3.14+ improving attribute lookup performance, enhancing free-threading safety for introspection, and better support for type annotations on dynamic objects, dir() is more reliable and useful than ever in concurrent code, plugin systems, and AI-assisted development. This March 23, 2026 update explains how dir() behaves today, real-world patterns, filtering techniques, and best practices for clean, maintainable introspection in modern Python.
TL;DR — Key Takeaways 2026
dir(obj)→ returns list[str] of attribute/method names (sorted)dir()with no argument → lists current scope (locals + globals)- 2026 best practice: Use dir() for debugging & exploration; filter results for production code
- Main use cases: interactive debugging, dynamic dispatch, plugin inspection, testing assertions
- Performance: Fast — C-level, but avoid in hot loops due to list creation
1. Basic Usage — Listing Attributes
class Person:
def __init__(self, name):
self.name = name
def greet(self):
return f"Hello, {self.name}"
p = Person("Alice")
print(dir(p))
# ['__class__',
# '__delattr__',
# '__dict__',
# ...,
# 'greet',
# 'name']
print(dir()) # current scope attributes
2. Real-World Patterns in 2026
Debugging & REPL Exploration
def inspect(obj):
print(f"Attributes of {type(obj).__name__}:")
for attr in dir(obj):
if not attr.startswith("_"):
print(f" {attr}")
inspect(p)
# Attributes of Person:
# greet
# name
Dynamic Method Dispatch / Plugin Inspection
def find_actions(obj):
return [name for name in dir(obj) if callable(getattr(obj, name)) and not name.startswith("_")]
print(find_actions(p)) # ['greet']
Testing / Assertion Helpers
def assert_has_attr(obj, attr_name: str):
if attr_name not in dir(obj):
raise AssertionError(f"Missing attribute: {attr_name}")
assert_has_attr(p, "greet")
3. dir() vs Alternatives – Comparison 2026
| Approach | Output | Dynamic? | Best For |
|---|---|---|---|
| dir(obj) | sorted list of str | Yes | General introspection |
| obj.__dict__.keys() | dict_keys of instance attrs | Yes | Only instance attributes |
| vars(obj) | dict of instance attrs | Yes | Readable dict view (not all objects) |
| inspect.getmembers(obj) | list of (name, value) tuples | Yes | Detailed inspection (value included) |
4. Best Practices & Performance in 2026
- Filter out dunders —
[a for a in dir(obj) if not a.startswith("_")] - Type hints 2026:
from typing import Any, Iterable def public_attrs(obj: Any) -> list[str]: return [a for a in dir(obj) if not a.startswith("_")] - Performance: dir() is fast but creates a list — avoid in very hot loops
- Free-threading (3.14+): Safe for reads; use locks if modifying attributes concurrently
- Avoid: dir() on very large objects (many attributes) — can be slow to list
Conclusion — dir() in 2026: Introspection Essential
dir() is the quickest way to discover what an object can do — perfect for debugging, REPL exploration, dynamic code, and testing. In 2026, use it with filtering, type hints, and caution in performance-critical paths. It’s simple, fast, and one of Python’s most powerful introspection helpers — essential for understanding any unknown object.
Next steps:
- Run dir() on your next unfamiliar object or module
- Related articles: Efficient Python Code 2026 • Python Built-ins Overview 2026