问题
I have the following directory structure:
py_test
├── __init__.py
├── dir1
│ ├── __init__.py
│ └── script1.py
└── dir2
├── __init__.py
└── script2.py
In script2
I want to "import ..\script1
".
What I tried in script2
:
Does not work
from ..dir1 import script1 ImportError: attempted relative import with no known parent package`
Works
import sys, os path2add = os.path.normpath(os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir, 'dir1'))) if (not (path2add in sys.path)) : sys.path.append(path2add)
If I want to go with option 1, what is the simplest (i.e., with the least files) file/dir structure that makes it work?
I am aware of this, but I wonder if creating that directory structure can be avoided, and still use type-1 import
.
I am currently using this workaround, which uses type-2 import
.
Related:
How to import a Python class that is in a directory above?
Import a module from a directory (package) one level up
Getting "ImportError: attempted relative import with no known parent package" when running from Python Interpreter
Using importlib to dynamically import module(s) containing relative imports
How to import variables in a different python file
回答1:
As mentioned in the comments, attempting to import modules a directory up will not work if script2.py
is your entry point.
As mentioned in this link you included:
If the module's
__name__
does not contain any package information (e.g., it is set to__main__
), then relative imports are resolved as if the module were a top-level module, regardless of where the module is actually located on the file system.
The module's __name__
is set to __main__
if it is the entry point, or the one that you pass to the interpreter with something like python script2.py
.
Any python module run as such no longer has the information needed to import files from higher directories.
Therefore you have two options:
Option 1: Keep using the workaround with sys.path.append
This will work how you want it to, but it is rather cumbersome.
Option 2: Make your entry point at the top level
Assuming your package has more than one script that needs to be run, you could create a new file that imports both script1
and script2
and then calls the functionality you want based on a command line argument. Then you will be able to keep your current directory structure and have your relative imports work just fine, without any kind of fiddling with sys.path
.
来源:https://stackoverflow.com/questions/59489786/yet-another-importerror-attempted-relative-import-with-no-known-parent-package