Here I discuss some techniques for python programming. These are not specifically related to this package, but influence some of the design.
A module is a directory with a __init__.py file as well as additional files. For example, consider mmf.math. This has a number of sub-modules, each with its own directory such as mmf.math.interp and mmf.math.integrate as well as some of its own functions such as mmf.math.EllipticF().
One common problem is the structure of the __init__.py file. The simplest option is an empty file. In this case, nothing will be imported unless it is specifically asked for.
If the module does not define any of its own entries, then the __init__.py file can be empty and python will deal with .py files and directories in the typical way, however, these will not be automatically imported or available in the module unless explicitly asked for by the user and not discoverable with tab completion etc. Also, a blank __init__.py file will not define any documentation.
Thus, we recommend the following skeleton for __init__.py files which uses mmf.utils.init:
from mmf.utils.init import get_imports as __get_imports
__delay__ = set()
__all__, __doc__, __imports = __get_imports(globals())
exec(__imports) # Remove this to delay everything.
del __get_imports, __imports, __delay__