Reputation: 337
I have a bunch of python scripts and simply want to structure them by putting most of them into subdirectories. However, when I try to load scripts from subdirectories, python gives me different error messages, depending on how I try to import the subdirectory scripts.
My subdir looks like this:
io
├── dataset_creator.py
└── read_data.py
In my script from the parent dir, when I do
from io import dataset_creator
this error occurs:
ImportError: cannot import name 'dataset_creator'
When I do
import io.dataset_creator
this error occurs:
ImportError: No module named 'io.dataset_creator'; 'io' is not a package
I also touched __init__.py
into io/ but it didn't help at all, as well as preceeding a dot to io/, but no luck. The python docs say I should add the __init__.py
and then everything should work, basically (as far as I interpreted it).
Can anyone help me here? If I left out some important info, please tell me and I'll add it.
Cheers, Jakob
EDIT:
As many of you stated, io is already another package in python, so renaming my io/ to something different fixed the problem (while also having the __init__.py
). Thank you very much!
I know there have been multiple correct answers, however, I could just mark one as correct, sorry.
Upvotes: 1
Views: 1547
Reputation: 1640
Recreating the problem:
mkdir io
touch dataset_creator.py
touch read_data.py
python3 -c 'from io import dataset_creator'
python3 -c 'import io.dataset_creator'
Gives the error messages.
Solution:
Explanation:
You are already in the io dir, so you don't need to specify the "io". You can simply do:
python3 -c 'import dataset_creator'
python3 -c 'import read_data'
And once you add a function or class in your python files:
def hello_world():
print("hello world")
You can import like this:
python3 -c 'from read_data import hello_world'
To organise your code under an io module umbrella, create another io directory as follows and use it to store your python code:
ia (parent dir where you do the import)
├── ia
│ ├── dataset_creator.py
│ └── read_data.py
├── .gitignore
├── requirements.txt
├── setup.py
└── README.md
python3 -c 'import ia.dataset_creator'
Note I renamed the directory to "ia" as well as there is already an "io" module that exists (ref).
Upvotes: 0
Reputation: 104682
The name io
is already being used by a standard library module. Since it's one of the very basic modules used by the interpreter, it gets loaded during the startup process, before any of your code runs. This means that by the time Python sees your request to import io.dataset_creator
, it's already got an io
module in sys.modules
. Since that module is not a package, it won't try loading the other submodule you've written in your io
package (even if you had a module search path set up so that your package came ahead of the standard library).
You should rename your io
package. One option is to put it inside another package (mypackage.io.dataset_creator
should work fine). You could also just replace the name io
with something more specific (e.g. myproject_io
).
Upvotes: 2
Reputation: 617
This happened to me as well on Python 3.5.1 when I tested it.
Renaming the directory io
to something else (I used my_io
) fixed the problem. Here was my test case:
main.py
my_io
├── module.py
└── something.py
Both modules imported correctly when I changed the directory's name. I suggest you change your io
directory to something similar to avoid this.
I think this must be to do with some internal Python module called io
which was conflicting somehow.
Upvotes: 0
Reputation: 31885
I have answered a similar question here Using exec on a file in a different directory causes module import errors
Append your parent path to Pythonpath:
import sys
sys.path.append("/path/to/parentfolder")
You can use os.path.dirname(__file__)
to get file's absolute path other than hardcoded path.
Add __init__.py to your parent folder and io folder, make the it as python package other than directory.
import the module:
import io.dataset_creator as dcreator
parent/
-- app.py
-- io/
--dataset_creator.py
--read_data.py
In you app.py:
import sys
sys.path.append(os.path.abspath(os.path.dirname(__file__)))
import io.dataset_creator as dcreator
Upvotes: 0
Reputation: 410
It's possible that that it's failing because io
is already a built-in module
Upvotes: 2