Python dir(): Discovering Object Attributes, Methods, and Scope Names

The dir() built-in function returns an alphabetically sorted list of valid attribute and method names for a given object or the current local scope.

Introspection & Attribute Discovery: Without arguments, dir() returns all identifiers defined in the current local scope. When passed an object, it inspects its __dir__() hook or underlying symbol tables to discover attributes, methods, and dunders. To retrieve actual attribute values in dictionary format, see vars(). For programmatic attribute retrieval, see getattr() and hasattr(), or consult formatted documentation with help().

1. Syntax & Parameter Specifications 🔝

The dir() function accepts up to one optional parameter and always returns a sorted list of strings:

# Formal syntax of built-in dir()
attribute_list = dir([object])
Parameter Type Default Description & Operational Rule
object Any Optional Target module, class, instance, or built-in whose attributes will be inspected.
Return list[str] N/A An alphabetically sorted list of attribute and method names.
No Argument Current Scope N/A Returns names bound within the caller's current local symbol table.

2. Inspecting Local Scope Without Arguments 🔝

Calling dir() without arguments lists all variables, imported modules, and functions bound in the current frame:

# 1. Inspecting current local scope without arguments
user_name = "Alex"
active_sessions = 12

# Calling dir() without arguments returns all names in the current scope
scope_names = dir()

print("User variables discovered in scope:")
print([name for name in scope_names if not name.startswith("_")])

Terminal Output:

User variables discovered in scope:
['active_sessions', 'scope_names', 'user_name']

3. Inspecting Modules, Collections & Built-ins 🔝

Passing a module or class identifier reveals all public members and internal special methods:

# 2. Inspecting module and data structure attributes
import math

# Discovering functions and constants in the math module
math_symbols = dir(math)
print("Total symbols in math:     ", len(math_symbols))
print("Sample trigonometric items:", [s for s in math_symbols if "sin" in s or "cos" in s])

# Inspecting built-in list methods
list_methods = [m for m in dir(list) if not m.startswith("_")]
print("Public list methods:       ", list_methods)

Terminal Output:

Total symbols in math:      55
Sample trigonometric items: ['acos', 'acosh', 'asin', 'asinh', 'cos', 'cosh', 'sin', 'sinh']
Public list methods:        ['append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']

4. Customizing Introspection with __dir__() 🔝

When dir(object) is called, Python checks if the object implements a custom __dir__() method. Defining __dir__() allows classes to expose a curated attribute list:

# 3. Customizing attribute discovery with __dir__()
class SecureVault:
    def __init__(self, owner, secret_key):
        self.owner = owner
        self._secret_key = secret_key

    def unlock(self):
        return "Vault open"

    def __dir__(self):
        # Explicitly control which attributes appear in dir() inspection
        return ["owner", "unlock"]

vault = SecureVault("plus2net", "classified_99")
print("Controlled dir() output:", dir(vault))

Terminal Output:

Controlled dir() output: ['owner', 'unlock']

5. Filtering Public Methods vs. Special Dunders 🔝

To inspect only user-accessible methods, filter out attributes starting with underscores:

# 4. Filtering public methods vs. special dunders
class AccountService:
    service_id = "SVC-01"

    def deposit(self, amount):
        pass

    def withdraw(self, amount):
        pass

# Filter only public callable methods
public_methods = [
    attr for attr in dir(AccountService)
    if not attr.startswith("_") and callable(getattr(AccountService, attr))
]

print("Public callable methods:", public_methods)

Terminal Output:

Public callable methods: ['deposit', 'withdraw']

6. Comparative Analysis: dir() vs. vars() vs. help() 🔝

Choosing the appropriate introspection tool:

Feature dir() vars() help()
Return Type list[str] (sorted names) dict (name → value mapping) None (prints text manual)
Values Included No (names only) Yes (maps keys to bound values) Yes (signatures & descriptions)
Inherited Attributes Yes (traverses inheritance tree) No (only instance/class __dict__) Yes (full class hierarchy)

7. Production Recipe: Dynamic Plugin Hook Runner 🔝

Discover and invoke plugin event handler methods dynamically at runtime:

# 5. Production Recipe: Dynamic Plugin Hook Runner
class AnalyticsPlugin:
    def hook_on_login(self, user):
        return f"Analytics: {user} logged in"

    def hook_on_logout(self, user):
        return f"Analytics: {user} logged out"

    def internal_utility(self):
        pass

def trigger_hooks(plugin_instance, hook_event, *args):
    """Discovers and executes methods matching the hook pattern dynamically."""
    target_name = f"hook_{hook_event}"
    available_methods = dir(plugin_instance)
    
    if target_name in available_methods:
        method = getattr(plugin_instance, target_name)
        if callable(method):
            return method(*args)
    return None

plugin = AnalyticsPlugin()
print(trigger_hooks(plugin, "on_login", "David"))
print(trigger_hooks(plugin, "on_logout", "David"))

Terminal Output:

Analytics: David logged in
Analytics: David logged out

8. Common Developer Pitfalls & Traps 🔝

Attributes created dynamically through __getattr__() or dynamic property getters do not appear in dir() unless the class explicitly implements __dir__():

# 6. Common traps: dynamic attributes not appearing in dir()
class DynamicBag:
    def __getattr__(self, name):
        # Attribute is dynamically created on access
        if name.startswith("dynamic_"):
            return "Generated value"
        raise AttributeError(name)

bag = DynamicBag()
print("Direct dynamic access:   ", bag.dynamic_field)
print("Field in dir(bag)?       ", "dynamic_field" in dir(bag))

Terminal Output:

Direct dynamic access:    Generated value
Field in dir(bag)?        False

9. Interactive Notebook & Practice Exercises 🔝

Practice object introspection, attribute filtering, and custom __dir__() overrides in our interactive companion Jupyter Notebook:

Interactive Companion Jupyter Notebook

Explore interactive code cells, inspect standard library modules, implement custom __dir__() methods, and run self-validating assertions.

View on GitHub Run in Google Colab

Self-Verifying Assertion Suite

Run these unit checks directly in Python or your local environment to verify dir() mechanics:

# 7. Self-verifying unit test suite for dir()
import math

# Test 1: dir() returns a list
assert isinstance(dir(), list), "dir() must return a list"

# Test 2: Standard methods on list
list_attrs = dir([])
assert "append" in list_attrs and "extend" in list_attrs

# Test 3: Module introspection
assert "pi" in dir(math) and "sqrt" in dir(math)

# Test 4: Custom __dir__() override
class CustomDiscover:
    def __dir__(self): return ["alpha", "beta"]

assert dir(CustomDiscover()) == ["alpha", "beta"]

# Test 5: Sorted order invariant
attrs = dir(str)
assert attrs == sorted(attrs), "dir() results must be alphabetically sorted"

print("All dir() unit assertions successfully verified!")

Terminal Output:

All dir() unit assertions successfully verified!

10. Frequently Asked Questions (FAQ) 🔝

Are dir() results always sorted?

Yes. Python guarantees that dir() returns an alphabetically sorted list of string attribute names.

Does dir() show inherited attributes?

Yes. Unlike vars() or __dict__, dir() inspects the object, its class, and all base classes recursively.

How do I filter out dunder methods?

Use a list comprehension: [attr for attr in dir(obj) if not attr.startswith('__')].

Why would a class override __dir__()?

To expose dynamically generated attributes (such as proxy or delegate properties) to interactive shells like IPython and auto-completers.

Further Reading & Related Tutorials 🔝




Subscribe to our YouTube Channel here



plus2net.com







Python Video Tutorials
Python SQLite Video Tutorials
Python MySQL Video Tutorials
Python Tkinter Video Tutorials
✖
We use cookies to improve your browsing experience. . Learn more
HTML MySQL PHP JavaScript ASP Photoshop Articles Contact us
© 2000-2026 plus2net.com All rights reserved worldwide Privacy Policy Disclaimer