0

I want to organize my python project like so:

/proj
   /test
      __init__.py
      test.py
   /utils
      __init__.py
      util.py

Inside test.py I have want to import a class from utils.util

from utils.util import classA

However, I get an error when I run test.py when I am in the /proj directory:

$ python test/test.py 
Traceback (most recent call last):
  File "test/test.py", line 1, in <module>
    from utils.util import classA
ImportError: No module named utils.util

However, if I make these changes, the code runs fine (python test.py)

/proj
   test.py
   /utils
      __init__.py
      util.py

I would really like to be able to organize my code like I did at the first example without getting errors. How can I enable myself to do this?

Liondancer
  • 15,721
  • 51
  • 149
  • 255

3 Answers3

2

You can run it as a package.

python -m test.test
Sayan Chowdhury
  • 419
  • 4
  • 13
2

How importing works

When you try to import a module, Python searches through directories in PYTHONPATH, looking for the module you are importing.

So, when you write from utils.util import classA, it looks for directory named utils, which contains file util.py (and __init__.py, but that is a different issue). Directory utils must be on your PYTHONPATH.

What happens in your case

You can see what is on your path if you put this in the script:

import sys
print sys.path

When you print that, you will probably see it contins an empty string ''. That means the directory where your script (test.py) is. So, if utils direcory is in the same place where test.py is, Python will be able to find it. Otherwise it won't.

How to fix it

Make sure utils is on the path. There are different ways to do that, e.g.

  • put your entry script in the root (as in your example which works); or
  • add the root directory to the PYTHONPATH environment variable before running python test.py
  • add the root directory to the sys.path from within test.py before importing anything

Edit: or, as Sayan wrote:

  • run it as python -m test.test (do that from the root directory)
zvone
  • 18,045
  • 3
  • 49
  • 77
0

You can do module relative imports. Try:

from ..utils.util import classA

in your test.py

Felk
  • 7,720
  • 2
  • 35
  • 65