Reputation: 21261
I know this is a dumb question but i'm stumped. My directory structure used to look like this:
-src
|
-module.py
-program.py
when this what my directory structure, I referenced module from program and all was well.
I've since changed my directory structure to this:
-src
|
-__init.py
-module.py
|
-programDir
|
-__init.py
-program.py
now, of course, I can't reach the module from program. How can I reference src as a package. I tried to create an
__init__.py
file in the src directory, but no luck.
Moar deets: import statements i've tried in program.py:
import module
and
from src import module
the first one worked when the other module and program were in the same directory.
error i'm getting:
ImportError: No module named module
and just for the record: No, my module and program are not called module OR program
update: I've tried this in my program.py file:
from ...src import module
and
from ..src import module
both are giving me:
ValueError: Attempted relative import in non-package
Upvotes: 0
Views: 2276
Reputation: 55752
If you use program as part of a package, in another python module, such as
import src.programDir.program as p
p.some_method()
you can use relative import in program.py, assuming you are creating a package with src (__init__.py
in both src and programDir)
from .. import module
If not, for example you are calling program.py from the command line, you must add the directory containing src to your search path either by modifying sys.path
or the PYTHONPATH env var, before importing.
Upvotes: 0
Reputation: 18570
For starters, I recommend reading the entry Modifying Python's Search Path in the docs.
It might be frowned upon by some, but if you wish to modify the PYTHONPATH from within your program, according to the documentation's standard modules entry you can use the sys.path.append method:
import sys
sys.path.append('..')
import module
Upvotes: 2
Reputation: 33640
You need to add __init__.py
to /programDir
to interpret the directory as a package. Once a package, you can import the package's contents.
So, in your case, if /src
is on the PYTHONPATH
, from module.py
you can import program.py
with from programDir import program
.
Upvotes: 0
Reputation: 24919
The first one worked because Python's sys.path
's first entry is '' which means it will look for module names in the current working directory from which you've executed the Python interpreter.
The issue you seem to have is that the directory located at src
is not set on your PYTHONPATH. So, you can do is set the PYTHONPATH environment variable explicitly.
Here's an example using bash:
export PYTHONPATH=PATH_TO_SRC:${PYTHONPATH}
then run your program as normal
Another approach is that you can explicitly set sys.path
by appending to it upon execution of your program.
So, in your program.py
, you would have:
if __name__ == '__main__':
import os
import sys
sys.path.append(os.path.dirname(os.path.dirname(__file__)))
your_main_function()
Lastly, for serious python development, you should consider virtualenv and virtualenvwrapper as it will take care of most of these things for you.
Upvotes: 0
Reputation: 75437
If you run program.py
directly, with python program.py
or with #!
, then module.py
's directory should be in the PYTHONPATH for import module
to work. This can be achieved using a helper shell script that's kept in programDir
, for instance, and looks something like:
#!/bin/bash
script_dir=`dirname $0`
# Add the script's parent directory to the PYTHONPATH
export PYTHONPATH=$PYTHONPATH:$script_dir/..
python $script_dir/program.py
Another, probably better, way would be to have program.py
export a "main()
" function, and create a helper python script at src/program
that looks like:
#!/usr/bin/env python
from programDir.program import main
main()
In this case, you can use relative imports in src/programDir/program.py
, so this should work:
from .. import module
Upvotes: 0