10

Hierarchy:

scripts/
    web/
        script1.py
    tests/
        script2.py
common/
    utils.py

How would I import utils in script1 and script2, and still be able to run those scripts seperately (i.e., python script1.py). Where would I place the __init__.py files, and is that the correct way to go about this? Thank you!

Jared Zoneraich
  • 561
  • 1
  • 5
  • 13

1 Answers1

9
package/
    __init__.py
    scripts/
        web/
            __init__.py
            script1.py
        tests/
            __init__.py
            script2.py
    common/
        __init__.py
        utils.py

I've added a bunch of empty __init__.py files to your package. Now you have 2 choices, you can use an absolute import:

 from package.common import utils

or equivalently:

 import package.common.utils as utils

The downside here is that package must somehow be on PYTHONPATH. The other option is to use relative imports:

from ....common import utils

I would generally discourage this approach... It just gets too hard to tell where things are coming from (is that 4 periods or 6?).

mgilson
  • 300,191
  • 65
  • 633
  • 696
  • When I try running script1.py using the relative import, I get the error: `ValueError: Attempted relative import in non-package` – Jared Zoneraich Jul 18 '13 at 17:48
  • That's because when you run it as a stand-alone program, python doesn't know it's in a package (It didn't get there by following a trail of `__init__.py` files). This is another reason why I prefer the more explicit version. – mgilson Jul 18 '13 at 18:10
  • Hmmm so I just tried using absolute imports, and now it can't find the module. What do I have to do to `PYTHONPATH`? Thanks! – Jared Zoneraich Jul 18 '13 at 18:14
  • @JaredZoneraich -- That depends on your OS. On *NIX using sh as you shell, it would be something like `export PYTHONPATH=${PYTHONPATH}:/path/to/package` – mgilson Jul 18 '13 at 18:15
  • Thanks, but is there anyway that I can accomplish this without changing env variables? – Jared Zoneraich Jul 18 '13 at 18:21
  • You can also append to the python path before you try to import the module: `import sys; sys.path.append('path/to/package'); import package` – mgilson Jul 18 '13 at 19:14
  • You might want to see [this](http://stackoverflow.com/questions/11536764/attempted-relative-import-in-non-package-even-with-init-py) answer to get more insight. – narayan Aug 10 '15 at 16:46