Reputation: 455
I want to ask you something that came to my mind doing some stuff.
I have the following structure:
src
- __init__.py
- class1.py
+ folder2
- __init__.py
- class2.py
I class2.py I want to import class1 to use it. Obviously, I cannot use
from src.class1 import Class1
cause it will produce an error. A workaround that works to me is to define the following in the __init__.py
inside folder2
:
import sys
sys.path.append('src')
My question is if this option is valid and a good idea to use or maybe there are better solutions.
Another question. Imagine that the project structure is:
src
- __init__.py
- class1.py
+ folder2
- __init__.py
- class2.py
+ errorsFolder
- __init__.py
- errors.py
In class1
:
from errorsFolder.errors import Errors
this works fine. But if I try to do in class2
which is at the same level than errorsFolder
:
from src.errorsFolder.errors import Errors
It fails (ImportError: No module named src.errorsFolder.errors
)
Thank you in advance!
Upvotes: 8
Views: 13980
Reputation: 839
There is also a solution that does not involve the use of the environment variable PYTHONPATH.
In src/
create setup.py
with these contents:
from setuptools import setup
setup()
Now you can do pip install -e /path/to/src
and import to your hearts content.
-e, --editable <path/url> Install a project in editable mode (i.e. setuptools "develop mode") from a local project path or a VCS url.
Upvotes: 3
Reputation: 140148
Despite the fact that it's slightly shocking to have to import a "parent" module in your package, your workaround depends on the current directory you're running your application, which is bad.
import sys
sys.path.append('src')
should be
import sys,os
sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)),os.pardir))
to add the parent directory of the directory of your current module, regardless of the current directory you're running your application from (your module may be imported by several applications, which don't all require to be run in the same directory)
Upvotes: 4
Reputation: 77902
from ..class1 import Class1
should work (at least it does here in a similar layout, using python 2.7.x).
As a general rule: messing with sys.path
is usually a very bad idea, specially if this allows a same module to be imported from two different paths (which would be the case with your files layout).
Also, you may want to think twice about your current layout. Python is not Java and doesn't require (nor even encourage) a "one class per module" approach. If both classes need to work together, they might be better in a same module, or at least in modules at the same level in the package tree (note that you can use the top-level package's __init__
as a facade to provide direct access to objects defined in submodules / subpackages). NB : I'm not saying that your current layout is necessarily wrong, just that it might not be the simplest one.
Upvotes: 1
Reputation: 49
No, Its not good. Python takes modules in two ways:
To find out what is included in $PYTHONPATH, run the following code in python (3):
import sys
print(sys.path)
By help of these two ways you can full-fill the need to create a python project.
Upvotes: -1
Reputation: 249103
One correct way to solve this is to set the environment variable PYTHONPATH
to the path which contains src
. Then import src.class1
will always work, regardless of which directory you start in.
Upvotes: 3