Whatever I try, since I switched to Python 3 I can run scripts with imports only from the root folder of the project, but not from subfolders. I am aware that there are lots of questions here about the error messages I get, but the proposed solutions don't work for me. Could someone please provide a sample solution for this small sample project? I am sure it would be appreciated by many.
proj
├── foofolder
│ ├── __init__.py
│ └── foofile.py
├── subfolder
│ ├── __init__.py
│ └── run.py
└── __init__.py
I define the function foofun()
in foofile.py
, and want to call it in run.py
.
If run.py
is directly in proj
it works. But (just to keep things organized) I want to have it in a subfolder - which surprisingly seems impossible.
The annoying thing is that autocomplete in my IDE (PyCharm) suggests that from foofolder.foofile import foofun
should work. But it does not. Nor does any other import I could imagine:
from foofolder.foofile import foofun
--> ImportError: No module named 'foofolder'
from .foofolder.foofile import foofun
--> SystemError: Parent module '' not loaded, cannot perform relative import
(Same with two dots at the beginning.)
from proj.foofolder.foofile import foofun
--> ImportError: No module named 'proj'
Not even the absolute import works. Why does it not find proj
?
sys.path
is: ['/parent/proj/subfolder', '/parent/env/lib/python35.zip', '/parent/env/lib/python3.5', '/parent/env/lib/python3.5/plat-x86_64-linux-gnu', '/parent/env/lib/python3.5/lib-dynload', '/usr/lib/python3.5', '/usr/lib/python3.5/plat-x86_64-linux-gnu', '/parent/env/lib/python3.5/site-packages']
I use Python 3.5.2 in a virtualenv.
Edit: I was wrong when I suggested that this problem is specific to Python 3. Problem and solution were the same when I checked in Python 2.7.12.
The solutions given by Pevogam work. The first one literally adds just '..'
to 'sys.path'
, which describes the parent folder of wherever run.py
is executed. The second explicitly adds '/parent/proj'
.
The solution I had looked for is the -m
switch:
$ python -m proj.subfolder.run
(Note the dots instead of slashes.)
I am always glad, when I can avoid complications like sys.path.append
.
See also: What is the purpose of the -m switch?
In a Django project I found this also useful:
$ python manage.py shell < app/utils/scripts/script.py
Found here: How to execute a Python script from the Django shell?