Python: module with submodules

Run a program containing submodules

Assume we have the following layout:
module_with_sub_module: the directory that contains the application(It is not the base module directory but a directory that holds it ).
foo/app: a submodule
foo/business: a submodule
foo/core: a submodule

module_with_sub_module

And here the main program:

from foo.business.FooClass import FooClass
 
 
def main():
    foo = FooClass()
    input = 'lion'
    output: str = foo.do_foo(input)
    print(f'input={input},output={output}')
 
 
if __name__ == '__main__':
    main()

Type of errors encountered

Error when we execute the application from the root module:
Execute the application in this ways trigger a ModuleNotFoundError:
module_with_sub_module$ python3.9 foo/app/Main.py

Traceback (most recent call last):
  File "/home/david/python-workspace/python_blog_examples/module_with_sub_module/foo/app/Main.py", line 8, in <module>
    from foo.business.FooClass import FooClass

If we print the value of sys.path, we could see that the base module is not inside it, only the module of the executed program/file is in it: /home/david/python-workspace/python_blog_examples/module_with_sub_module/foo/app

sys.path=['/home/david/python-workspace/python_blog_examples/module_with_sub_module/foo/app',
'/usr/lib/python39.zip', '/usr/lib/python3.9', '/usr/lib/python3.9/lib-dynload', '/home/david/.local/lib/python3.9/site-packages', '/usr/local/lib/python3.9/dist-packages', '/usr/lib/python3/dist-packages']

Solution:
Add the working directory, that is also here the project root directory in sys.path.
You have mainly 2 ways to do that:
– Updating sys.path before importing any submodules in the main program:

sys.path.append(os.getcwd())

If the error persists, you can print the value of sys.path.
So the main program could look like finally :

import os
import sys
 
# PYTHONPATH
sys.path.append(os.getcwd())
print(f'after sys.path={sys.path}')
 
from foo.business.FooClass import FooClass
 
 
def main():
    foo = FooClass()
    input = 'lion'
    output: str = foo.do_foo(input)
    print(f'input={input},output={output}')
 
 
if __name__ == '__main__':
    main()

– Updating the PYTHONPATH env variable before launching the program:
export PYTHONPATH=.:${PYTHONPATH}

Error because of missing __init__.py files:
You must add __init__.py in the submodules where you have the import errors.

Ce contenu a été publié dans Non classé. Vous pouvez le mettre en favoris avec ce permalien.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *