4

I have a python project which needs to be able to run external scripts.

These scripts are dynamically imported in a directory structure with several modules.

Now, as these scripts are written independently and are unaware of each other, they often use the same modules names.

This makes it problematic for me when importing them one after the other.

For example, here's my directory structure:

  • main.py
    • a
      • a.py
      • utils.py
    • b
      • b.py
      • utils.py

So I have a main.py script in the root folder and 2 "external" scripts in a and b folders.

Both scripts use a different utils.py module.

Contents of a/a.py:

import utils
utils.hello()

Contents of a/utils.py:

def hello():
    print 'hello from a'

Contents of b/b.py:

import utils
utils.hello()

Contents of b/utils.py:

def hello():
    print 'hello from b'

Contents of main.py

import sys
sys.path.append('a')
import a
sys.path.append('b')
import b

Now, this example prints:

hello from a
hello from a

And I obviously need it to print:

hello from a
hello from b

As I'm not in-charge of the "external" scripts and I cannot modify them, is there any way I can accomplish this?

edit

Using @moinuddin-quadri answer of importing like: from a import a indeed works for this easy example, but what about this:

  • main.py
    • a
      • a.py
      • lib
        • utils.py
      • lib2
        • utils2.py
    • b
      • b.py
      • lib
        • utils.py
      • lib2
        • utils2.py

Where each utils.py is doing:

from lib2 import utils2

For this to work I need the root script folder to be on sys.path

When b/lib/utils tries to run: from lib2 import utils2, it receives the utils2 in a/lib2

Guy Erlich
  • 73
  • 1
  • 10

2 Answers2

2

You should be using relative imports in a.py and b.py. So, your imports should be like:

from . import utils

which means from current directory, import utils. This way you ask your python program to import a/utils.py in a/a.py and b/utils.py in b/b.py.

Firstly create a __init__.py in the directory having main.py (assuming __init__.py is alread present in a and b) and then import a and b in main.py as:

from a import a   # No need to do `sys.path.append('a')`
from b import b

# For importing utils.py  (if needed)
from a import utils as a_utils
a_utils.hello()

from b import utils as b_utils
b_utils.hello()

Also read:

Community
  • 1
  • 1
Moinuddin Quadri
  • 46,825
  • 13
  • 96
  • 126
0

Normally, to import modules, we don't need to use sys.path:

main.py

from a import a
# first 'a' is the directory. second 'a' is a.py
# the 'a' directory needs to have __init__.py which can be blank
from b import b

a/a.py

from . import utils

b/b.py

from . import utils

Since you cannot modify the external modules, you can rename the modules that have the same names when you import them:

main.py

from a import utils as utils_a
from b import utils as utils_b

utils_a.hello()
utils_b.hello()
ooknosi
  • 374
  • 1
  • 2
  • 8
  • Thanks, but as I said, I cannot modify the contents of a.py and b.py and I also do not import utils. a.py and b.py do the import. – Guy Erlich Jan 15 '17 at 07:55