简体   繁体   中英

Python3.5 import from subdirectory doesn't work

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.

因为io已经是内置模块 ,所以失败了

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 (eg myproject_io ).

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

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.

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:

  1. Create another sub-directory called "io" and put the files there.
  2. Use a name different than "io", as a module by that name already exists.

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 ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM