3

I am trying to import a module from a python file that is in a sibling folder. I read several similar questions here and tried to apply solutions listed there, but I wasn't able to solve the problem.

The structure is as follows:

parentfolder/gfolder/codefolder/fileA.py
parentfolder/gfolder/utilfolder/util.py

gfolder, codefolder and utilfolder all have an __init__.py.

I'm trying to do in fileA.py:

import gfolder.utilfolder.util as util

I also tried adding before the import statement:

sys.path.append(".../parentfolder/")

And that didn't work either:

import gfolder.utilfolder.util as util
ModuleNotFoundError: No module named 'gfolder'

The solution in a similar question says to include __init.py__ in the directories, which I already have.

EDIT: Now both sys.append and sys.insert work and the problem was that I included a slash at the end of the path. When I took it out, everything worked.

jack_pl
  • 41
  • 1
  • 5
  • 1
    Possible duplicate of [Python import module from sibling folder](https://stackoverflow.com/questions/14886143/python-import-module-from-sibling-folder) – Tzomas Feb 08 '18 at 17:08

2 Answers2

3

First of all, let me describe you the differences between a Python module & a Python package so that both of us are on the same page. ✌


A module is a single .py file (or files) that are imported under one import and used. ✔

import aModuleName # Here 'aModuleName' is just a regular .py file.

Whereas, a package is a collection of modules in directories that give a package hierarchy. A package contains a distinct __init__.py file. ✔

from aPackageName import aModuleName # Here 'aPackageName` is a folder with a `__init__.py` file # and 'aModuleName', which is just a regular .py file.


Therefore, when we have a project directory named proj-dir of the following structure ⤵

proj-dir --|--__init__.py --package1 --|--__init__.py --|--module1.py --package2 --|--__init__.py --|--module2.py

Notice that I've also added an empty __init__.py into the proj-dir itself which makes it a package too.

Now, if you want to import any python object from module2 of package2 into module1 of package1, then the import statement in the file module1.py would be

from proj-dir.package2.module2 import object2 # if you were to import the entire module2 then, from proj-dir.package2 import module2

I hope this simple explanation clarifies your doubts on Python imports' mechanism.

Sushant Rajbanshi
  • 1,985
  • 1
  • 19
  • 20
  • 1
    Hi @Sushant Chaudhary, I have a question will this work if the script runs from package1 module1? I am trying it and it seems to me that pythons imports will only work if called from a file that is above all imports. E.g in this example I would need a main.py in Proj-dir if this main.py is my entry point all imports will work but if I run package2 module2 directly I will get a "ValueError: attempted relative import beyond top-level package" is this how it works? – Remigius Kalimba Jr Aug 08 '19 at 11:03
  • 1
    It actually doesn't work this way, your parent package does not appear in sys.path automatically. See more here: https://stackoverflow.com/questions/6323860/sibling-package-imports/50193944#50193944 – Azamat Galimzhanov May 27 '20 at 12:18
  • 2
    This answer **does not work** if you call the script (module) directly, you must use `python -m project.package1.module1` instead. – Levi Lesches Jun 11 '21 at 19:40
  • With the equivalent layout `ModuleNotFoundError: No module named proj-dir` is raised – scrollout Oct 30 '22 at 00:30
1

As Andrew Cox answerd int the following thread Import a module from a relative path

You can add the subdirectory to your Python path so that it imports as a normal script

import sys
sys.path.insert(0, <path to gfolder>)
import gfolder

you can also add the directory to the PATH var of the Linux system (I use it while I'm working on a project, at the end i modified the PATH to it's origin value)

if you maintain the following structre than it is working out side the box

parentfolder/gfolder/codefolder/fileA.py
parentfolder/gfolder/utilfolder/util.py
parentfolder/gfolder/main.py

run main.py

shahaf
  • 4,750
  • 2
  • 29
  • 32