2

I've read many docs over the last few days about relative Python imports but run into a struggle with the following folder structure:

parent_folder
       ├── subfolder1
       │        └── __init__.py
       │        └── file_1.py
       ├── subfolder2
       │        └── __init__.py
       │        └── file_2.py
       │
       └ __init__.py (parent folder has an init in it)

In file_2.py I would like to access the functions in file_1.py. I've tried adding the following to file_2.py but none seem to work:

1. from ..subfolder1 import file_1    #ImportError: attempted relative import with no known parent package

2. import parent_folder.subfolder1.file_1    #ModuleNotFoundError: No module named 'parent_folder'

3. from parent_folder.subfolder1 import file_1    #ModuleNotFoundError: No module named 'parent_folder'

I'm really lost right now and can't seem to understand why this is occuring. I've probably read 10 different guides on relative imports now and still can't figure out why.

Note, if I put file_2.py inside parent_folder, and then add import subfolder1.file1 it imports well, but I can't move file_2.py from it's position or use sys.path.append()

Does anyone with more module experience than I have any insight? Thank you!

mmarion
  • 859
  • 8
  • 20
  • Does this answer your question? [Relative imports in Python 3](https://stackoverflow.com/questions/16981921/relative-imports-in-python-3) – Sven Eberth May 27 '21 at 00:28

3 Answers3

2

The answers advising messing with the sys path are wrong - unfortunately this advice is floating over the web causing infinite frustration and crashes (good) to subtle bugs (bad).

The correct answer is running your script using the -m switch from the parent folder of the top most package. So if this parent_folder is a package as it looks it is and you want to run file_1.py you should

$ python -m parent_folder.subfolder1.file_1

any of the three imports would work then

Mr_and_Mrs_D
  • 32,208
  • 39
  • 178
  • 361
  • 1
    this was perfect, exactly what I was looking for! And thank you for understanding the `sys.append` problem. I've been told on multiple occasions to not use that in prod envs and even put it in my question that I'd rather not use it, but that always seems to be everyone's go-to answer when I post anything about Python packages _sigh_ – mmarion May 27 '21 at 16:47
  • I understand this point, and there are also similar solution applicable to packages, like the one mentioned in https://stackoverflow.com/questions/14057464/relative-importing-modules-from-parent-folder-subfolder However, not everything is a package, and I find the solution with sys.append to be useful e.g., when working in a jupyter notebook. – Vincenzooo Aug 09 '23 at 13:23
1

Change Path

Make sure you change sys.path before you start importing anything so you don't get an error when importing

So, begin with this:

import os, sys

path = os.path.join(os.path.dirname(__file__), os.pardir)
sys.path.append(path)
0

In my case I did this

import sys
sys.path.insert(0, '..')

then

from parent_folder.subfolder1.file_1 import --the-function-needed--
Ariel Anasco
  • 55
  • 2
  • 11