Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to import a module from a subfolder in python3 (with empty __init__.py)

I want to call a function from a file in a sub folder. I would prefer do do it statically. I use empty __init__.py files as I've read that in simple cases they can be empty(and mine couldn't be an simpler) or that from 3.5 on I don't need them at all. But I am open to filling them.

I have the following file structure:

test
├── callfoo.py   (main)
├── __init__.py  (empty)
└── folder
    ├── submodule.py
    └── __init__.py (empty)

callfoo.py:

#import statement wanted

def main():
    foo()

if __name__ == "__main__":
        main()

submodule.py

def foo():
    print('foo')

For the import statement I've tried:

import test.folder.submodule
from test.folder import submodule
from test.folder.submodule import foo

each resulting in ModuleNotFoundError: No module named 'test.folder' I'm a bit confused here because they are taken straight from the Documentation

import .folder.submodule -> invalid syntax importlib.import_module('test.folder.submodule') ModuleNotFoundError: No module named 'test.folder'

This works:

import importlib.util
spec = importlib.util.spec_from_file_location("submodule", "/home/.../test/folder/submodule.py")
foo = importlib.util.module_from_spec(spec)
spec.loader.exec_module(foo)

But I don't really want to do it dynamically especially not for several files.

This ModuleNotFoundError: No module named x deals with my error message but not with subfolders as far as I can tell (it works fine for me with submodule.py on the same level as callfoo.py)

There are several questions dealing with imports from sub folders but I couldn't make them work for me. I hope to have provided a dead simple problem formulation.

like image 701
peer Avatar asked Jan 06 '18 17:01

peer


1 Answers

Let's suppose we have this folders/files architecture:

test
├── callfoo.py
└── folder
    ├── __init__.py
    └── submodule.py

1 directory, 3 files

callfoo.py:

from folder.submodule import foo

def main():
    foo()

if __name__ == '__main__':
    main()

submodule.py:

def foo():
    print('foo in submodule')

now place your self at the same level's folder of callfoo.py and run:

$ python3 callfoo.py

Output:

> foo in submodule
like image 169
Chiheb Nexus Avatar answered Sep 20 '22 13:09

Chiheb Nexus