Modules and Packages
- The very basic: Every source file is a module. The import module will load AND execute a module.
- Modules are a namespace for the definitions inside, and as expected, a layer over a Python dictionary (the globals of that module).
Special variables:
__file__
(name of source file), __name__
(name of the module) and __doc__
. -> The main module: __name__ == __main__
.
import foo
in bar.py
: Executes foo
and adds a reference to foo
in bar.__dict__
from foo import func
: foo
still executes, but only func
is added to bar
’s dictionary
from foo import *
: All names that don’t start with underscore get added to bar
- Each module is loaded only once. Use
sys.modules
to get a list of loaded modules.
- Module reloading (with
importlib
): This is not advised, since existing instances of classes will still use old code, specific names imported from foo import name
don’t get updated, and can break typechecks/ code with super()
- Module import basics: Relative imports of submodules don’t work - imports are always absolute
- Packages:
__package__
(name of the enclosing package), __path__
(search path for subcomponents)
- Main use of
__init__.py
: stitching together multiple source files into a “unified” top-level import
- Controlling exports: Submodules should define
__all__
to control from module import *
. This is useful in __init__
!
__main__.py
designates an entrypoint for a package! Makes the module executable python -m module
- Inject dynamic import magic with
__import__
or importlib
. Can do things like __import__(f"{__package__}.formats.{format}")
(this imports a file from .formats
if present)