Package imports
When developing Python packages/modules, you will often want to break your functions into multiple scripts and sub-modules. You will use the __init__.py files throughout the package to import functionality from the .py script files you write.
Over time, as the module grows, certain methods of importing functions & objects from the module's packages will cause slowdowns and errors. Python has an __all__ dunder method to control what is exported from a .py file. Adding defined functions, variables, and objects to the __all__ list for a package allows you to write a simple from .script_name import * in the module's __init__.py.
Example package
The following is an example of a Python module. Pretend you're building an app, and you created a packages/ directory in the repository root. Each directory in packages/ represents a Python package, an isolated collection of modules which contain .py scripts with functionality you want to import into the rest of your app.
In packages/example/, you are writing "helper" functions for operations like path and string manipulation.
example/
├── __init__.py
├── io
│ ├── __init__.py
│ └── pathio.py
└── str_ops
├── __init__.py
└── _manipulate.py
Each __init__.py imports the __all__ list from the associated .py file. For example, the example/io/__init__.py file's contents are:
example/io/pathio.py
In example/io/pathio.py, there are functions defined and a variable called __all__, which is a list of strings matching functions and/or variables in the pathio.py file:
Importing the example.io.pathio module
Only the functions/variables defined in __all__ will be available with from example.io import pathio. For example:
example/str_ops/
The same is true for example.str_ops, which imports the _manipulate.py's functions with __all__.
This module exports the example_var, unlike example.io.pathio's example_var.
Importing the example.str_ops module
The example.str_ops.__init__.py file imports everything from _manipulate.py:
| example/str_ops/__init__.py | |
|---|---|
This makes the to_uppercase, to_lowercase, to_titlecase, remove_word_from_str, functions are available, as well as the example_var variable:
Summary
By adding an __all__ list variable to your Python module scripts, you can control what is exported. This way, you can have private variables/functions accessible only from within the .py script file, and public/exported objects that are available when you import the module in another script.
Using an __all__ list also simplifies your imports in __init__.py files. You can simply use from .script_name import *, which will only import what's listed in that file's __all__.