0

I have the following directory structure. And I'm in ..

./ # current directory
  __init__.py
  module_1/
    __init__.py
    util
      __init__.py  # contains f1(), f2(), ...
    test.py

The following python command works fine

python -c "from module_1.util import f1, f2"

Running in REPL works fine too.

Python 3.8.11 (default, Aug  6 2021, 09:57:55) [MSC v.1916 64 bit (AMD64)] :: Anaconda, Inc. on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from module_1.util import f1, f2
>>>   

However, execute the test.py got the error of ModuleNotFoundError: No module named 'module_1'. test.py has only one line

from module_1.util import f1, f2

Run script:

(base) PS C:\Users\X\src> python .\module_1\test.py
Traceback (most recent call last):
  File ".\module_1\test.py", line 1, in <module>
    from module1.util import f1, f2
ModuleNotFoundError: No module named 'module_1'
ca9163d9
  • 27,283
  • 64
  • 210
  • 413
  • have you tried `from ..module_1.util import f1, f2` ? (where the double `..` moves up one level in the dir) – Schalton Oct 04 '21 at 14:13
  • It got the error of `ImportError: attempted relative import with no known parent package` if adding `..`. – ca9163d9 Oct 04 '21 at 14:15
  • You might need an empty `__init__.py` in your test dir – Schalton Oct 04 '21 at 14:16
  • ohh and you need an `__init__.py` in you `module_1` dir – Schalton Oct 04 '21 at 14:17
  • basically `__init__.py` tells python that things can be imported from that directory. You can do things like in `module_1/__init__.py` write `from .util import f1, f2` which would then let you import `f1` and `f2` directly from `module_1` – Schalton Oct 04 '21 at 14:18
  • 1
    @Schalton, actually I have `__init__.py` in module_1. Why the command `python -c "from module_1.util import f1, f2"` works (tried in REPL too) but not in the script? – ca9163d9 Oct 04 '21 at 14:32
  • I think you need to create a proper package (using setup.py); I updated my answer below – Schalton Oct 04 '21 at 14:55
  • Does this answer your question? [Python project directory structure / pytest trouble](https://stackoverflow.com/questions/26804421/python-project-directory-structure-pytest-trouble) – Schalton Oct 04 '21 at 14:56

2 Answers2

0

You could try using the name of the dir ".", which I will call DOT dir, and do something like:

from DOT.module_1.util import f1, f2

you may need to add the DOT dir or the parent of the DOT dir to your PYTHONPATH variable.

Also add the __init__.py in test

and the f1() f2() should be in the util.py file

Isy89
  • 179
  • 8
  • Yep, lots of people put all of their code in a "`src`" directory – Schalton Oct 04 '21 at 14:22
  • yep, generally should be src for convention, but I don't know how the "." dir was called in this case. Didn't want to create confusion. – Isy89 Oct 04 '21 at 14:28
  • @lsy89, wasn't criticizing the response, just giving the tidbit to OP in case they decided to take this approach. -- For simple projects this is likely what I would do, the only downside is if they become more complex you can end up with circular dependencies – Schalton Oct 04 '21 at 14:33
0
./
  setup.py
  __init__.py
  module_1/
    __init__.py
    util
      __init__.py  # contains f1(), f2(), ...
  test/
    __init__.py
    test.py

in test.py:

from module_1.util import f1,f2

in setup.py

from setuptools import setup
setup(name='module_1', packages=['module_1'])

"install" [link] with python setup.py develop


Optionally you could add the import to the module_1/__init__.py as follows:

# module_1/__init__.py
from .util import f1, f2

which would allow you to import it directly in test.py

# test.py
from ..moduel_1 import f1, f2
Schalton
  • 2,867
  • 2
  • 32
  • 44