Python tutorials > Modules and Packages > Packages > What is `__all__` in packages?
What is `__all__` in packages?
The __all__
variable in a Python package or module is a list of strings defining the public interface of that module or package. It's used to control what names are imported when a user imports the module or package using from package import *
or from module import *
. It essentially acts as an explicit allow list, preventing accidental exposure of internal functions and variables.
Basic Example of `__all__` in a Module
In this example, my_module.py
defines two functions: public_function
and _private_function
. The __all__
list only includes 'public_function'
. When a user does from my_module import *
, only public_function
will be imported.
# my_module.py
def public_function():
return "This is a public function"
def _private_function():
return "This is a private function"
__all__ = ['public_function']
Importing with `__all__`
This code demonstrates how __all__
affects imports. Attempting to use _private_function
directly after from my_module import *
will result in a NameError
because it was not included in the __all__
list in my_module.py
.
# main.py
from my_module import *
print(public_function())
# This will raise an error because _private_function is not imported
# print(_private_function())
Example in a Package
In a package, the __init__.py
file often contains the __all__
variable. This controls which submodules or names within those submodules are exposed when the package itself is imported. Here, we import specific functions from module1
and module2
and make them part of the package's public interface through __all__
.
# my_package/__init__.py
from .module1 import public_function1
from .module2 import public_function2
__all__ = ['public_function1', 'public_function2']
Concepts Behind the Snippet
The main concept behind __all__
is explicit control over the public API of your modules and packages. This helps in:
Real-Life Use Case Section
Consider a scientific library. The library might contain numerous internal helper functions and classes. Using __all__
, the library developers can carefully expose only the core functions and classes that are intended for users, making the library easier to understand and use. This also allows the developers to change internal implementations without impacting external users who are only using the documented public API.
Best Practices
__all__
so that users understand how to use your module or package.__all__
helps control the import, it's generally better to use explicit imports for clarity.
Interview Tip
When discussing __all__
in an interview, emphasize its role in defining and maintaining a clean public API. Highlight its importance for code maintainability, preventing namespace pollution, and enabling refactoring without breaking external code. Mention that explicit imports are generally preferred over from module import *
, even with __all__
defined.
When to Use Them
Use __all__
in the following situations:
Memory Footprint
__all__
itself has a very small memory footprint. It is simply a list of strings, and the memory used to store the list is generally negligible. The real memory impact comes from the objects that are made available to the user. Properly using __all__
can indirectly help improve memory efficiency by preventing the unnecessary loading of modules or definitions that are not intended for public use. This is because only the items in __all__
are imported when using the wildcard import.
Alternatives
While __all__
is the standard way to control wildcard imports, an alternative is to rely solely on explicit imports in your code. This means avoiding from module import *
altogether and always specifying the exact names you want to import. While more verbose, explicit imports provide better clarity and avoid the potential pitfalls of wildcard imports, even with __all__
defined.
Pros
Cons
__all__
list whenever the public API changes.__all__
will make it inaccessible via wildcard imports.
FAQ
-
What happens if `__all__` is not defined?
If
__all__
is not defined in a module or package,from module import *
will import all names that do not begin with an underscore (_
). However, relying on this implicit behavior is generally discouraged. Defining__all__
explicitly makes your intentions clear and provides better control over the public API. -
Can `__all__` contain names that are not defined in the current module?
Yes,
__all__
can contain names that are defined in other modules but are re-exported in the current module. This is common in package__init__.py
files where you want to aggregate functions from different submodules into a single, convenient interface. -
Does `__all__` affect explicit imports?
No,
__all__
only affects wildcard imports (from module import *
). Explicit imports, such asimport module
orfrom module import specific_name
, will always import the specified names regardless of what is in__all__
.