1

I have a Python 3.9.2 project with the following directory structure:

lib/
├─ mod1.py
├─ mod2.py
├─ __init__.py
main.py

In /main.py, I have from lib import mod1. In /lib/mod1.py, I have import mod2. When I run /main.py, I receive the following error:

Traceback (most recent call last):
  File "/main.py", line 1, in <module>
    from lib import mod1
  File "/lib/init.py", line 1, in <module>
    import mod2
ModuleNotFoundError: No module named 'mod2'

Why is this happening? When I change the code in /lib/mod1.py to say from lib import mod2, the code works fine, but I don't understand why that fixes it. Shouldn't I be able to import /lib/mod2.py the way I originally tried, since both mod1.py and mod2.py are in the same directory?

Ben Zelnick
  • 433
  • 4
  • 14

1 Answers1

2

In /lib/mod1.py, you probably want to do:

# relative import - entire module
from . import mod2

# relative import - specific piece
from .mod2 import foo 

or

# absolute import - entire module
from lib import mod2

# absolute import - specific piece
from lib.mod2 import foo

The correct way to import things is really tricky in Python because it depends on where you run the script from.

  • If you run the code from the root directory, import mod2 causes problems, but
  • If you were to run /lib/mod1.py (say it were run-able) from inside lib, then import mod2 would be correct and the alternatives above would cause errors.
Dustin Michels
  • 2,951
  • 2
  • 19
  • 31
  • It worked for me when I used `from . import mod2`, but not with `import .mod2`. If I wanted to ensure that the script was run-able, would I have to use `if __name__ == "__main__"` to check whether it was being run as an independent script? – Ben Zelnick Mar 27 '21 at 16:34
  • Ah, that was a syntax error. Fixed! You don't need `if __name__ == "__main__"` to make a script run-able, but its a good practice. See: https://stackoverflow.com/questions/419163/what-does-if-name-main-do – Dustin Michels Mar 27 '21 at 16:55
  • Sorry, I wasn't clear. Can using `if __name__ == "__main__"` be used to check whether to run `import mod2` (as you said at the bottom of your post, this might cause an error depending on how the script is run)? – Ben Zelnick Mar 28 '21 at 16:56