0

I'm having problems understanding the way import, absolute and relative, works in Python.

I'll reproduce my working directory and omit some files for brevity:

A/
  B/
  __init__.py
  main.py
  C/
    __init__.py
    module1.py
    module2.py

main.py needs f1 and f2 from module1.py. module1.py needs f3 from module2.py.

After tinkering and reading documentation I got to import functions to my main.py file from my module1.py file. I had to do the following inside main.py:

from .C.module1 import f1, f2.

module1.py depends on functions from module2.py. That is trivial: inside module1.py:

from module2 import f3.

This way I can call module1.py directly and it will load f3; however, in my main.py (which is a Flask app, by the way), it won't load, because module1.py throws ModuleNotFoundError: No module named 'module2'. I think that has to do with the fact that I'm in a different directory now. Anyways, if in module1.py I change from module2 import f3 to from .module2 import f3, main.py will work, but then I can't call the module1.py file directly because it will throw an ModuleNotFoundError: No module named '__main__.module2'; '__main__' is not a package exception.

EDIT: accidentally swapped names.

Notice that I have __init__.py in both directories/packages. What should I do so that both main.py and module1.py work?

AtilioA
  • 419
  • 2
  • 6
  • 19

1 Answers1

1
test
├── C
│   ├── __init__.py
│   ├── module1.py
│   └── module2.py
└── main.py

test/main.py

from C import f1, f2, call_f3

print(f1())
print(f2())
print(call_f3())

test/C/module1.py

from .module2 import f3

def f1():
    return "f1()"

def call_f3():
    return "called " + f3()

test/C/module2.py

def f2():
    return "f2()"


def f3():
    return "f3()"

test/C/__init__.py

This is what allows us to do from C import f1, f2, call_f3 in main.py.

from .module1 import f1, call_f3
from .module2 import f2

Output of main.py

f1()
f2()
called f3()
felipe
  • 7,324
  • 2
  • 28
  • 37
  • This is basically my setup (`__init__.py` from `C/` is blank). In the way you've set up, if I do `python module1.py` I will get an `ModuleNotFoundError: No module named '__main__.module2'; '__main__' is not a package` exception. – AtilioA Jan 16 '20 at 17:27
  • 1
    Because you are relatively importing `module2` from `module1`. Check out this post [here](https://stackoverflow.com/a/16985066/1305461) for more info. – felipe Jan 16 '20 at 17:30
  • 1
    What you have to keep in mind, is Python uses the import directories (`import .module` vs `import ..module` vs `import module`) relative to the directory you call `python file.py` from -- this is the easiest way to remember how relative/absolute imports work in Python. – felipe Jan 16 '20 at 17:33
  • This is way more complicated than it should be. I don't really know if I understood, but the answer you linked made it work. I'll read more. – AtilioA Jan 16 '20 at 17:49