3

Setup

test/
    main.py
    pkg/
        a.py
        __init__.py

main.py contains:

import pkg    
pkg.a

__init__.py contains:

from . import a

main.py can be run without errors.

Question

Changing the content of __init__.py to

import a

gives the following error when running main.py:

Traceback (most recent call last):
  File "C:/Users/me/PycharmProjects/test/main.py", line 1, in <module>
    import pkg
  File "C:\Users\me\PycharmProjects\test\pkg\__init__.py", line 1, in <module>
    import a
ModuleNotFoundError: No module named 'a'

Interestingly, __init__.py can be executed directly with python __init__.py without errors.

What's going on?

actual_panda
  • 1,178
  • 9
  • 27

2 Answers2

4

When you run a python script, it's parent folder is added to sys.path

  • run main.py: sys.path[0] = '../test'
  • run init.py: sys.path[0] = '../test/pkg'

Your case: You try to "absolute-like" import a in __init__.py but the parent folder of a.py - which is '../test/pkg' - is not in the sys.path when you run main.py. This is why you get an error. However, your absolute import is incomplete as it should always start at the top level folder, e.g.

from test.pkg import a

Final answer to your question: You don't have to use relative imports!

See: PEP-8: Absolute imports are recommended, as they are usually more readable and tend to be better behaved (or at least give better error messages) if the import system is incorrectly configured (such as when a directory inside a package ends up on sys.path).

And keep in mind that relative imports don't work in a top-level-script when __name__ = "__main__", but from imported modules only.

You can learn more about absolute and relative imports here:
Absolute vs. explicit relative import of Python module
https://realpython.com/absolute-vs-relative-python-imports/

Peter
  • 10,959
  • 2
  • 30
  • 47
  • Thanks. I understand the words you wrote but I don't understand them as an answer. :/ – actual_panda Apr 18 '20 at 09:50
  • Thanks. For some reason I can never use the Python import system intuitively, despite reading what feels like every article on the internet about it. – actual_panda Apr 19 '20 at 08:26
1

I suppose you are using Pycharm? Then that's one of the confusion cause.

For example, let's say your directory looks like this

project1
    p1.py
    test/
        __init__.py
        main.py
        pkg/
            a.py
            __init__.py

If you run (F10) the main.py your default working directory will be project1/test, which does not contain the a.py so import a will not find anything.

But if you run (F10) the pkg/__init__.py your working directory will be project1/test/pkg which has the a.py, and it works like what you tested.

So in these situation, if you use from . import a it will look for the directory that file is, project1/test/pkg in this case, which will always work regardless your working directory.

Natthaphon Hongcharoen
  • 2,244
  • 1
  • 9
  • 23