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
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…