0

I have code in one folder, and want to import code in an adjacent folder like this:

I am trying to import a python file in innerLayer2, into a file in innerLayer1
outerLayer:
           innerLayer1
                      main.py
           innerLayer2 
                      functions.py

I created the following function to solve my problem, but there must be an easier way? This only works on windows aswell and I need it to work on both linux and windows.

# main.py
import sys    
def goBackToFile(layerBackName, otherFile):
        for path in sys.path:
            titles = path.split('\\')
            for index, name in enumerate(titles):
                if name == layerBackName:
                    finalPath = '\\'.join(titles[:index+1])
                    return finalPath + '\\' + otherFile if otherFile != False else finalPath


    sys.path.append(goBackToFile('outerLayer','innerLayer2'))
    import functions

Is there an easier method which will work on all operating systems?

Edit: I know the easiest method is to put innerLayer2 inside of innerLayer1 but I cannot do that in this scenario. The files have to be adjacent.

Edit: Upon analysing answers this has received I have discovered the easiest method and have posted it as an answer below. Thankyou for your help.

Zak Stucke
  • 432
  • 6
  • 18
  • I have typed the answer and then found a possible duplicate https://stackoverflow.com/questions/14057464/relative-importing-modules-from-parent-folder-subfolder – user3159253 Mar 20 '18 at 00:27
  • Possible duplicate of [Relative importing modules from parent folder subfolder](https://stackoverflow.com/questions/14057464/relative-importing-modules-from-parent-folder-subfolder) – user3159253 Mar 20 '18 at 00:29

4 Answers4

2

Use . and .. to address within package structure as specified by PEP 328 et al.

Suppose you have the following structure:

proj/
     script.py       # supposed to be installed in bin folder
     mypackage/      # supposed to be installed in sitelib folder
         __init__.py # defines default exports if any
         Inner1/
             __init__.py    # defines default exports from Inner1 if any
             main.py
         Inner2/
             __init__.py    # defines default exports from Inner2 if any
             functions.py

Inner1.main should contain import string like this:

from ..Inner2 import functions
user3159253
  • 16,836
  • 3
  • 30
  • 56
  • This would work if I was dealing with a package, in my scenario this just leads to ValueError: attempted relative import beyond top-level package – Zak Stucke Mar 20 '18 at 00:36
  • I have stumbled upon the perfect answer to my problem and have posted it as an answer. Thankyou – Zak Stucke Mar 20 '18 at 00:41
1

If you have to use the current directory design, I would suggest using a combination of sys and os to simplify your code:

import sys, os
sys.path.insert(1, os.path.join(sys.path[0], '..'))
from innerLayer2 import functions
PixelEinstein
  • 1,713
  • 1
  • 8
  • 17
  • This works well thankyou but have stumbled upon even simpler syntax which works just aswell, I have posted it as an answer for your interest. – Zak Stucke Mar 20 '18 at 00:42
1

Upon analysing answers I have received I have discovered the easiest solution: simply use this syntax to add the outerLayer directory to sys.path then import functions from innerLayer2:

# main.py
import sys
sys.path.append('..') # adds outerLayer to the sys.path (one layer up)
from innerLayer2 import functions 
Zak Stucke
  • 432
  • 6
  • 18
0

The easiest way is:

Move the innerLayer2 folder to inside the innerLayer1 folder
Add an empty file named __init__.py on the innerLayer2
On the main.py use the following:

 import innerLayer2.functions as innerLayer2
 # Eg of usage:
 # innerLayer2.sum(1, 2)
Adriano Martins
  • 1,788
  • 1
  • 19
  • 23
  • In this scenario I cannot put the innerLayer2 inside innerLayer1, if i could put it inside one another then I would use sys.append('innerLayer2) then just import functions instead of your method. – Zak Stucke Mar 20 '18 at 00:18
  • @user3159253 provided a generic answer which does not require any changes on your structure – Adriano Martins Mar 20 '18 at 00:36