0

I was writing this, and then I realized many people had this same issue and many 'workarounds' were given, but I haven't seen one that is really satisfactory.

This answer got 1000 upvotes, but it doesn't work for me (I suppose it's for python 2).

This one also has many upvotes, but most of the solutions simply don't work for this layout, or it's super complicated.

Anyway, given this file structure:

folder/
  mylib/
    __init.py__
    MyClass.py
  src/
    main.py

init.py

MyClass.py:

class MyClass:
    def __init__(self):
        self.x = 0

main.py

# import sys
# sys.path.append('.') # Only works if I have this! 
from mylib.MyClass import MyClass
m = MyClass()
print(m.x)

Running python src/main.py from the root folder/ gives:

ModuleNotFoundError: No module named 'mylib'

The easist solution I found is modifying sys.path (uncommenting the code above), but it still feels a bit hacky. Alternatively, if main.py is on the root folder it also works, but I don't want to have dozens of files cluttering the root directory.

This answer says that "one should structure the files into packages", but doesn't say how that is done. Is there still no better alternative?

Bersan
  • 1,032
  • 1
  • 17
  • 28
  • 1
    Add an empty file `__init__.py` in src directory – Prayson W. Daniel Aug 11 '21 at 15:16
  • Also add `__init__.py` to their shared parent directory, might be necessary. Python will treat a folder as a path it can import from only if `__init__.py` is present in it. – Green Cloak Guy Aug 11 '21 at 15:18
  • 1
    Traditionally, if `mylib` is specifically for this project then it should be in `src` with `main.py` and thus directly importable. If it's meant to be shared across multiple projects it can use a structure similar to the one you have, but `src` would be a project in itself with a virtual environment that has `mylib` installed into it (possibly as an editable install for ease of modifying things). Basically, `mylib` is either part of the source for this project or it's a package of its own. – Kemp Aug 11 '21 at 15:20

1 Answers1

0

Ether you make folder a real Python module or just execute it as a module:

/tmp/folder >> tree                                                                                                                                                          .
├── mylib
│   ├── MyClass.py
│   └── __init__.py
└── src
    └── main.py

2 directories, 3 files

Running as module (from within folder):

python3 -m src.main                                                                                                                                           
0
Maurice Meyer
  • 17,279
  • 4
  • 30
  • 47