5.19. Writing modules¶
Any .py file is a module. Splitting a growing script across a
few files keeps each file short and lets common helpers be shared
between scripts.
5.19.1. Splitting a script¶
Pull a related group of functions out into their own file:
camera_utils.py:
def banner():
print("OpenMV")
def label(text):
return "[" + text + "]"
main.py:
import camera_utils
camera_utils.banner()
print(camera_utils.label("ready"))
Output:
OpenMV
[ready]
The two files sit side by side in the same directory. When
main.py runs, import camera_utils reads
camera_utils.py once, executes its top-level statements, and
binds the resulting module object to the name camera_utils in
main. A second import camera_utils from anywhere else
returns the same object – modules are cached after their first
load.
A module’s name comes from its filename, so camera_utils.py
gets imported as import camera_utils.
5.19.2. Multi-file modules (packages)¶
A module can also be a directory of files rather than a single
.py. The directory’s name becomes the module name, and the
files inside are its submodules:
camera_utils/
__init__.py
text.py
timing.py
__init__.py is the file that runs when the package itself is
imported; it can be empty, or it can re-export selected names
from the submodules. The submodules are reached with a dotted
name:
import camera_utils.text
from camera_utils.timing import elapsed
camera_utils.text.label("ready")
Inside the package, submodules can reach each other either by the full dotted name or by a relative import that uses a leading dot to mean “this package”:
camera_utils/timing.py:
from . import text # the sibling submodule
def stamp(value):
return text.label(str(value))
To pull in a specific name instead, name it after the dotted sibling:
from .text import label
def stamp(value):
return label(str(value))
Relative imports keep a package self-contained: renaming the package directory does not require editing every submodule.
Use a package when a single file grows past a comfortable size,
or when a set of related modules belongs together under one
namespace. For everyday scripts a single .py file is enough.
5.19.3. The __name__ guard¶
Every module has a built-in name __name__. Its value depends
on how the file is being used:
When the file is run directly,
__name__is set to the string"__main__".When the file is imported by another script,
__name__is set to the module name – the filename without.py.
The idiom that uses this is:
label_util.py:
def label(text):
return "[" + text + "]"
if __name__ == "__main__":
print(label("self-test"))
Output (when run directly):
[self-test]
When the same file is imported instead, __name__ is set to
the module name, so the if block is skipped and nothing extra
runs:
>>> import label_util
>>> label_util.__name__
'label_util'
Use the pattern to attach a quick smoke test or demo to a library file without disturbing scripts that import it.