简体   繁体   中英

Will an empty __init__.py interfere with a direct import and cause an error?

Some code has been refactored to make imports direct and there is a bit of a mess with reverted commits etc.. I am getting an ImportError and don't understand the Python import system well enough to know why. Have spent a long time looking at comparisons between branches etc but just can't find what it is..

Given the following directory structure,

our_project/
    __init__.py
    directory1/
        __init__.py
        file1.py
        file2.py
        file3.py
    directory2/
        __init__.py
        file3.py
        file4.py
        file5.py
    directory3/
        __init__.py
        file6.py
        file7.py
        file8.py

All the __init__.py 's are empty except the one in the our_project/ directory which has some code in it.

Would the following at the top of directory3/file7.py work, and not cause an ImportError :

from out_project.directory1.file1 import my_function

Or do you need to write

from our_project.directory1 import my_function ?

It just feels as if this empty __init__.py is somehow interfering with things..

The top-level package suggested by your folder layout is our_project . That means the folder containing it should be in the Python search path.

Then you can do absolute imports from anywhere with from our_project.directory1.file1 import my_function .

From the my_project.directory3.file7 module, you could instead use a relative import, from ..directory1.file1 import my_function .

The relative import might not work though if you're running file7.py as a script (with eg python file7.py on the command line). It's generally a bad idea to run scripts that are in a package by filename, as the interpreter won't be able to tell where they're supposed to be put in the package hierarchy. Instead, use python -m our_project.directory4.file7 to run the module by its absolute name.

Here is an link to the python docs which has a nice tutorial where all of it is explained.

The init .py files are just there to tell python to treat that directory as a python package so i believe how you would import depends on which packages is installed on the system (it searches you PYTHONPATH to find installed packages/modules). If just the our_project package in your example is installed you would need to import like

 from our_package.directory1.file1 import my_function

You could also use an relative import which would work regardless of what is installed

  from .directory1.file1 import my_function

The documentation on packages is here: https://docs.python.org/3/tutorial/modules.html#packages

Info on the module search path is here: https://docs.python.org/3/tutorial/modules.html#the-module-search-path

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