Norghar
Norghar

Reputation: 3

Importing modules from separate paths in Python

I'm trying to import modules from separate paths but the error it's returning is "module not found." It's importing modules from the directory the script is executed in but will not change directories and import from said directory.

print(os.getcwd())

When I run this, before it throws the error it couldn't find the module, it will output the parent directory so for example I'll go with test\import\modules.

I'll run a script in \import\ to import test_0.pyd from \import\ and test_1.pyd from \modules (test.py and test_0 being located in \import\ and test_1 being located in \modules. Also, I have tried relative importing and every directory contains init.py).

import test_0 # this would work
from modules import test_1 # throws error that module isn't found

So I run the print command and it returns that it's trying to import from test\ and I've tried changing directories but it'll say the working directory changed when I print, but still outputs that it couldn't find the module. Any help is greatly appreciated, thank you.

EDIT http://prntscr.com/6ch7fq - executing test.py http://prntscr.com/6ch80q - import directory

Upvotes: 0

Views: 652

Answers (2)

Josh Smeaton
Josh Smeaton

Reputation: 48710

When you start python from a directory, that directory is added to your PYTHONPATH so modules are importable from that directory and below, provided you've got an __init__.py in each directory, including the top level that you're running python from. See here:

~/Development/imports $ tree . ├── __init__.py ├── mod1 │   ├── __init__.py │   ├── a.py ├── mod2 │   ├── __init__.py │   ├── b.py ├── top.py

So when we start python from ~/Development/imports/, we can access top mod1.a and mod2.b:

~/Development/imports $ python
Python 2.7.8 (default, Nov  3 2014, 11:21:48)
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.54)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import top
>>> import mod1.a
>>> import mod2.b
>>> import sys

But when we start python from inside mod1, we're not allowed to go outside of mod1 back to top or to mod2:

~/Development/imports/mod1 $ python
Python 2.7.8 (default, Nov  3 2014, 11:21:48)
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.54)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import a
>>> from .. import top
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: Attempted relative import in non-package
>>> from ..mod2 import b
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: Attempted relative import in non-package

Relative imports from ..mod2 import b only work from a module below the top level module that you started from, because they are all implicitly in the python path.

You can't escape outside of the module you start from unless that particular path is added to PYTHONPATH or sys.path:

~/Development/imports/mod1 $ PYTHONPATH=../ python
Python 2.7.8 (default, Nov  3 2014, 11:21:48)
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.54)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import a
>>> import top
>>> import top.mod2.b
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named mod2.b
>>> import sys
>>> sys.path.append('~/Development/imports/mod2/')
>>> from mod2 import b
>>>

So, you need to ensure that all of your directories have an __init__.py file in them. You also need to ensure that you're starting python from the right location, usually the top directory. You can't start python half way down the directory structure and expect to get back up to the top, or sideways to another directory/module.

Upvotes: 2

viczsaurav
viczsaurav

Reputation: 37

Do you have __init__.py file in the said modules/directory? This is required for python to treat it as a package.

Check out What is __init__.py for?

Upvotes: 0

Related Questions