What does the __all__ attribute mean in Python, and how is it used in __init__.py files?
The __all__ attribute in Python is a special list that defines which names should be exported when a module is imported using wildcard syntax (from module import *). In __init__.py files, it controls which modules and functions are considered part of a package’s public API when users perform wildcard imports from the package.
Contents
- What is the
__all__Attribute? - How
__all__Works in Modules - Usage in
__init__.pyFiles - Best Practices and Examples
- Common Mistakes and Pitfalls
- Advanced Scenarios
What is the __all__ Attribute?
The __all__ attribute is a special list in Python modules that defines the public API of that module. When a user executes from module import *, only the names listed in __all__ are imported into the current namespace. If __all__ is not defined, all names that do not start with an underscore (_) are imported instead.
# In a module called mymodule.py
__all__ = ['public_function', 'PublicClass']
def public_function():
return "This is public"
def _private_function():
return "This is private"
class PublicClass:
pass
class _PrivateClass:
pass
In this example, when someone imports using from mymodule import *, only public_function and PublicClass will be available. The private functions and classes (those starting with underscore) are excluded.
How __all__ Works in Modules
The __all__ attribute follows specific rules:
- Definition: It must be defined at the module level as a list or tuple of strings
- Content: Each string must correspond to a valid name defined in the module
- Scope: It only affects wildcard imports (
from module import *) - Fallback: When
__all__is not defined, all names without leading underscores are imported
Here’s how it works in practice:
# Without __all__
def visible_function():
pass
def _invisible_function():
pass
# from module import * would import visible_function but not _invisible_function
# With __all__
__all__ = ['visible_function']
def visible_function():
pass
def _invisible_function():
pass
# from module import * would only import visible_function
It’s important to note that __all__ doesn’t affect regular imports like import module or specific imports like from module import specific_name. These import methods work regardless of the __all__ definition.
Usage in __init__.py Files
In __init__.py files, the __all__ attribute serves a crucial role in package structure. __init__.py files can be empty or contain code that initializes the package. When __all__ is defined in an __init__.py file, it determines which modules and subpackages are considered part of the package’s public API.
Here’s a typical example:
mypackage/
├── __init__.py
├── module1.py
├── module2.py
└── subpackage/
├── __init__.py
└── module3.py
# mypackage/__init__.py
__all__ = ['module1', 'module2']
# This makes module1 and module2 available via:
# from mypackage import *
This structure allows users to import from the package using a clean interface:
# Instead of:
from mypackage.module1 import function1
from mypackage.module2 import function2
# Users can do:
from mypackage import function1, function2
The __init__.py file can also be used to re-export functions and classes from submodules:
# mypackage/__init__.py
from .module1 import function1, function2
from .module2 import Class1
from .subpackage.module3 import function3
__all__ = ['function1', 'function2', 'Class1', 'function3']
This pattern creates a unified API where users don’t need to know the internal structure of the package.
Best Practices and Examples
When working with __all__, consider these best practices:
- Explicit is better than implicit: Always define
__all__to clearly specify the public API - Keep it up to date: Ensure
__all__contains all public names and doesn’t reference undefined names - Include docstrings: Document each item in
__all__to help understand the API - Consider versioning: Use
__all__to manage API changes between versions
Here’s an example of a well-structured __all__:
"""A comprehensive example of __all__ usage."""
__all__ = [
'public_function',
'PublicClass',
'CONSTANT',
'submodule',
]
def public_function():
"""A public function accessible via import *."""
return "public"
class PublicClass:
"""A public class accessible via import *."""
pass
_CONSTANT = 42 # Private constant
import .submodule as submodule
Common Mistakes and Pitfalls
Several common issues arise when working with __all__:
- Undefined names: Referencing names in
__all__that aren’t defined in the module - Missing names: Forgetting to include new public names in
__all__ - Incorrect ordering: Not maintaining logical order in the
__all__list - Over-reliance: Using
__all__as security (it’s not - it’s just a convention)
Example of a mistake:
# Incorrect: 'new_function' is not defined in this module
__all__ = ['public_function', 'new_function']
def public_function():
pass
This will cause AttributeError when someone tries to import using from module import *.
Advanced Scenarios
In more complex scenarios, __all__ can be used dynamically:
# Dynamic __all__ based on available features
try:
import expensive_module
__all__ = ['basic_function', 'expensive_function']
except ImportError:
__all__ = ['basic_function']
def basic_function():
"""Always available."""
pass
def expensive_function():
"""Only available if expensive_module is installed."""
return expensive_module.do_something()
Another advanced pattern is conditional exports:
# Conditional exports based on platform
import sys
if sys.platform == 'win32':
__all__ = ['windows_function']
else:
__all__ = ['unix_function']
def windows_function():
"""Windows-specific function."""
pass
def unix_function():
"""Unix-specific function."""
pass
Sources
- Python Language Reference - The import system
- Python Tutorial - Modules
- Python Documentation - Special module attributes
- PEP 8 - Style Guide for Python Code
Conclusion
The __all__ attribute is a powerful tool for managing Python module and package APIs. By explicitly defining which names should be exported, developers can create cleaner, more maintainable code interfaces. In __init__.py files, it serves as the package’s public contract, making it easier for users to work with complex packages without needing to understand their internal structure.
Key takeaways:
- Always define
__all__to make your module’s API explicit - In
__init__.py, use__all__to create a unified package interface - Keep
__all__synchronized with your actual public API - Remember that
__all__only affects wildcard imports - Use descriptive naming and maintain logical order in your
__all__lists
By following these practices, you’ll create more professional, user-friendly Python packages that are easier to understand and maintain.