Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.3k views
in Technique[技术] by (71.8m points)

python 3.x - Invalid relative import to parent folder

Given the following folder structure

scripts
    __init__.py
    prepare_dot_env.py
    random_folder
        __init__.py
        index.py

Take the import statement from ..prepare_dot_env import prepareDotEnvBot in scripts/random_folder/index.py.

When running python index.py inside scripts/random_folder, the ImportError: attempted relative import with no known parent package following exception is thrown.

According to the specification, assuming that both __init__.py files are empty, this should be fine. What's the catch here?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

TLDR: Execute the file as a module of the package:

$ python3 -m scripts.random_folder.index

If the package is not installed, this must be done from the folder containing scripts/ or by adding this folder to PYTHONPATH.


Relative paths work via package operations, not file system operations. A . means "one package up", not "one folder up". This means a relative . requires information about the current package position. The __package__ attribute contains this information:

This attribute is used instead of __name__ to calculate explicit relative imports for main modules, as defined in PEP 366. It is expected to have the same value as __spec__.parent.

The required information is set by qualified imports including the -m flag:

$ # script content: package metadata and import
$ cat scripts/random_folder/index.py
print(__package__)
print(__name__)
from ..prepare_dot_env import bar
print(bar)
$ # script as package member
$ python3 -m scripts.random_folder.index
scripts.random_folder
__main__
Placeholder to demonstrate import
$ # script as standalone executable
$ python scripts/random_folder/index.py
None
__main__
Traceback (most recent call last):
  File "scripts/random_folder/index.py", line 3, in <module>
    from ..prepare_dot_env import bar
ValueError: Attempted relative import in non-package

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...