__all__
Imagine you're building an API where you have code for both private and public consumption. For example, you have a public function that has private helper functions.
def public_function(...) -> ...:
...
private_function(...)
...
def private_function(...) -> ...:
...
In general, the pythonic way of resolving this is to preface with the
protected prefix _ to indicate internal consumption.
def _private_function(...) -> ...:
...
Clear signaling of what functions are for/not for public consumption is
helpful for maintaining and calling public APIs. However, on the flip
side, everything without _ is assumed to be public
implicitly. This could allow the import of non-public methods when using
from module import *. This is error prone.
The Solution: __all__
Another way to achieve this same effect is to explicitly signal with the
__all__ module attribute (although it looks like a dunder method,
it isn't!).
def public_func():
pass
def _private_func_mislabeled():
pass
def _another_func1():
pass
def another_func():
pass
__all__ = ['public_func', '_private_func_mislabeled'] # explicit control
# from mymodule import * will import: public_func, _private_func_mislabeled
# another_func is excluded even though it's "public" by naming
# _another_func1 is also excluded, as it should be.
This limits the blast radius of any changes to non-public functions, as
they won't be imported via import *. For example, if you
wanted
_another_func1 to be async, you could change it without worrying
about breaking external code that might have accidentally imported it.
Key Benefits
- Explicit API control: You decide exactly what's part of your public API
- Protection from accidental exports: Functions without underscore prefixes won't be accidentally exported
- Clear documentation:
__all__serves as a single source of truth for your module's public interface - Safer refactoring: Internal functions can be changed without worrying about breaking external code
- IDE support: Many IDEs use
__all__to provide better autocomplete suggestions
Questions or feedback? Feel free to reach out!