Python online course

Display and Inspect Module Contents in Python

Learn how to inspect Python modules with dir(), help(), __doc__, inspect.getmembers(), and inspect.signature().

When you import a Python module, you can explore the names it provides instead of guessing what is available. Python's built-in dir() function gives you a quick inventory, while help() and the standard-library inspect module provide documentation and callable details.

This lesson assumes that you know basic import statements, variables, functions, lists, and dot notation. For a refresher, see Import Modules and Interactive Prompt.

What a Python module contains

A module is an importable Python unit, commonly a .py file. A package can also contain importable module components. A module can define functions, classes, variables, constants, and documentation. It can also import names from other modules.

After import, the module has a module namespace: a mapping from names to objects. For example, a module named simple_module might make these names available:

  • Welcome, a function
  • Bye, another function
  • DEFAULT_LANGUAGE, a constant
  • names imported from another module
  • metadata such as __name__ and __file__

An attribute is a named value accessed with dot notation. For example, simple_module.Bye accesses the object named Bye in that module.

Names such as Welcome and Bye are user-defined names. Names surrounded by double underscores, such as __doc__, are usually special attributes used by Python or the import system. A module may also contain names beginning with one underscore, which conventionally indicates an internal or non-public name.

Import a module before inspecting it

You must first import a module and bind it to a name. The name used in the import statement refers to the module object in the rest of your code.

import simple_module

print(simple_module)

simple_module might be a local file in your project. Imported modules may also be built into Python, included in the standard library, installed from a third party, or supplied by another part of your project.

For example, math is a standard-library module:

import math

print(math.sqrt(25))

To learn how modules are created and organized, see What Are Modules.

Use dir() to display available names

dir() is a built-in function that returns a list of names associated with an object. Pass a module object to it with this syntax:

dir(module_name)

For a local module containing functions named Welcome and Bye:

import simple_module

print(dir(simple_module))

The result is a list of strings. It may contain names similar to these:

['Bye', 'Welcome', '__builtins__', '__cached__', '__doc__',
 '__file__', '__loader__', '__name__', '__package__', '__spec__']

The exact list depends on the module and the Python environment. dir() is excellent for quick exploration, but it only lists names. It does not fully describe what a function does, which arguments it expects, or whether a name is intended to be part of the module's public API.

Examples with a standard-library module

import math

names = dir(math)
print('pi' in names)
print('sqrt' in names)
print('factorial' in names)

This can help you discover constants such as math.pi and functions such as math.sqrt and math.factorial.

Common module-level special attributes

A dunder attribute is a special attribute whose name begins and ends with double underscores. Modules commonly expose metadata like the following:

Attribute | Purpose | Typical availability | Notes

__doc__ | Module documentation string | Often available | Its value can be None when no module docstring exists.

__name__ | The module's import name | Normally available | A directly executed file may have the value __main__.

__file__ | Source or module file location | Common for file-based modules | Built-in and frozen modules may not have a meaningful file path.

__package__ | Package context for importing | Common for imported modules | It is particularly important for relative imports.

__loader__ | Loader associated with the import | Often available | The loader explains how Python located and loaded the module.

__spec__ | Import metadata | Common for imported modules | It describes how the module was found and loaded.

__cached__ | Compiled-bytecode cache path | Often for file-based modules | It may be absent or have no useful path in some environments.

__builtins__ | Access to built-in names in the namespace | Common, but representation varies | Its exact form is an implementation detail and should not normally be edited.

Exact attributes and values depend on the Python version, import mechanism, module type, and execution environment. In particular, built-in, frozen, dynamically loaded, or otherwise non-file-based modules may not provide a useful __file__ or __cached__.

import simple_module

print(simple_module.__name__)
print(simple_module.__doc__)
print(getattr(simple_module, '__file__', None))
print(getattr(simple_module, '__cached__', None))

getattr(object, name, default) is useful when an attribute is optional. The example prints None instead of raising an exception if the metadata is not present.

Inspect an attribute inside a module

A module's names refer to objects, and each object can have its own attributes. Functions, classes, instances, and modules all have different sets of attributes.

import simple_module

print(dir(simple_module.Bye))
print(simple_module.Bye.__name__)
print(simple_module.Bye.__doc__)

For an ordinary Python function, useful metadata can include:

  • __name__: the function's name
  • __doc__: the function's docstring, or None
  • __module__: the module where the function was defined
  • __annotations__: optional type or parameter annotations
  • __defaults__: default values for positional parameters
  • __code__: the compiled code object
  • __globals__: the global namespace used by the function

A function's dir() output also contains many special methods and implementation details. These names are useful when learning how Python objects work, but they are not normally functions that you call directly as part of an application's API.

Find likely public names

By convention, a name beginning with an underscore is non-public. You can use a list comprehension to make a first-pass list of names that do not begin with an underscore:

import simple_module

public_names = [
    name for name in dir(simple_module)
    if not name.startswith('_')
]

print(public_names)

This may produce a result such as ['Bye', 'Welcome'], along with any public constants or imported names.

A module can also define __all__, an optional list of names intended for wildcard imports:

__all__ = ['Welcome', 'Bye']

__all__ often signals the module's public interface, but neither it nor underscore naming provides access control. Python code can still access a name beginning with an underscore, and a module can choose not to define __all__. Treat these features as API guidance rather than security mechanisms.

Get documentation and signatures

Use help()

help() opens interactive documentation in the Python interpreter. Give it a module or one of the module's attributes:

import simple_module

help(simple_module)
help(simple_module.Bye)

You can also read a docstring directly through __doc__:

print(simple_module.__doc__)
print(simple_module.Bye.__doc__)

A docstring is documentation stored on an object. It can explain a module's purpose, a function's parameters, return value, and usage.

Use inspect.getmembers()

The standard-library inspect module provides programmatic introspection. inspect.getmembers() returns sorted pairs containing member names and their values:

import inspect
import simple_module

members = inspect.getmembers(simple_module)
print(members)

You can filter the result to functions:

functions = inspect.getmembers(simple_module, inspect.isfunction)
print(functions)

This is useful when a program needs to analyze a module rather than merely display its names.

Use inspect.signature()

inspect.signature() displays a callable's parameter information when Python can obtain it:

import inspect

print(inspect.signature(simple_module.Bye))

The result might look like (name) or (), depending on how Bye was defined. Documentation and signatures may be unavailable or incomplete for some built-in functions, extension types, and other compiled objects.

Tool | What it reveals | Best use | Limitations

dir() | Names associated with an object | Quick discovery | Does not explain behavior or parameters.

help() | Interactive documentation | Learning intended usage | Depends on available documentation and terminal support.

object.__doc__ | A stored docstring | Reading documentation in code | The value may be None or incomplete.

inspect.getmembers() | Name-and-value member pairs | Structured discovery and filtering | Accessing members can have effects for dynamic objects.

inspect.signature() | Callable parameters | Understanding how to call a function | Some built-in or extension callables do not expose a signature.

How to interpret names from dir(module)

Name category | Examples | How to interpret it

Functions | Welcome, sqrt | Callable operations provided by the module.

Classes | A class defined in the module | Types that can be instantiated or inherited from.

Variables and constants | pi, DEFAULT_LANGUAGE | Values configured or calculated by the module.

Imported names | A name imported from another module | Available through this module, but not necessarily part of its intended public API.

Special module metadata | __name__, __spec__ | Information used by Python and the import system.

Private implementation names | _helper, __internal_value | Conventionally not intended for normal external use.

Practical limitations and safe interpretation

dir() may be customized by an object's __dir__ method. Therefore, its output is not always a simple dump of every value stored in the object's namespace. Dynamic modules and objects can expose names in special ways, and names in the result do not always correspond to ordinary stored attributes.

Do not rely on internal double-underscore attributes as stable application APIs. Import metadata can vary between environments, and special implementation details can change between Python versions.

Use dir() as a starting point, then confirm meaning and supported usage with help(), docstrings, official documentation, and source code when appropriate. The intended public API is the collection of names a module expects users to import or call; it is not necessarily every name returned by dir().

Troubleshooting inspection code

ModuleNotFoundError occurs during import

  • Confirm that the module file or installed package exists and that its name is spelled correctly.
  • Run the program with the intended interpreter and virtual environment.
  • Check the interpreter path and installed packages.
  • For a local project, run from the correct project context or use proper packaging. Avoid casually modifying sys.path.

An expected function is absent from dir(module)

  • The function may not be defined or imported by that module.
  • A different module with the same name may have been imported.
  • Module execution may have failed before the name was defined.
  • The module may expose names dynamically.
print(getattr(simple_module, '__file__', None))

When available, __file__ helps verify which local module Python imported. You can also use help(simple_module) and inspect.getmembers(simple_module).

__file__ or __cached__ is missing

The module may be built in, frozen, dynamically loaded, or loaded by a nonstandard importer. Use getattr(module, attribute, None) and treat import metadata as environment-dependent.

dir() shows too many special names

Filter names beginning with an underscore for a first pass:

names = [name for name in dir(simple_module) if not name.startswith('_')]

Then use help(), documentation, and __all__ when present to identify intended usage.

dir() does not explain how to call a function

Names alone do not provide usage instructions. Try all three of these tools:

help(simple_module.Bye)
print(simple_module.Bye.__doc__)
print(inspect.signature(simple_module.Bye))

Quick reference

import simple_module
import inspect

# List all discovered names
print(dir(simple_module))

# Keep likely public names
print([name for name in dir(simple_module)
       if not name.startswith('_')])

# Read module and function documentation
help(simple_module)
print(simple_module.Bye.__doc__)

# Discover members and functions
print(inspect.getmembers(simple_module))
print(inspect.getmembers(simple_module, inspect.isfunction))

# Inspect a callable's parameters
print(inspect.signature(simple_module.Bye))

After discovering a module's contents, consult Help Mode and learn more about the Python module system.