Python: 导入语句中无法识别父包的名称
Python: name of parent package not recognized in import statements
我知道有很多关于这个主题的问题,但我看到的大多数答案都描述了解决问题的复杂方法,在我看来,这些问题应该很简单。这是我的目录结构:
Mapper/
LICENSE.txt
README.txt
setup.py
bin/
# nothing here, yet
mapper/
__init__.py
process.py
where.py
# ...
binconvert/
__init__.py
tocsv.py
todict.py
# ...
我想在所有本地开发的模块上使用绝对路径以减少混淆并避免提到的错误 here。
但是,我遇到了很多问题。当我运行process.py
,其中我import
tocsv.py
这样,
from mapper.binconvert import tocsv
我收到错误:ModuleNotFoundError: No module named 'mapper'
我知道我可以做到 from binconvert import tocsv
,但就像我说的,我正在尝试让我所有本地开发的模块导入都使用绝对路径。
当我尝试像这样导入 where.py
时,我遇到了与之前在 tocsv.py
中相同的错误:
from mapper import where
对于这个,我相信有一些方法可以使用相对 import
的点语法,但同样,我想保持我所有的路径都是绝对的。毕竟,我相信根据 python 文档的 this 段,我应该能够做到这一点:
When packages are structured into subpackages (as with the sound package in the example), you can use absolute imports to refer to submodules of siblings packages. For example, if the module sound.filters.vocoder
needs to use the echo module in the sound.effects package
, it can use from sound.effects import echo
.
sound/ Top-level package
__init__.py Initialize the sound package
formats/ Subpackage for file format conversions
__init__.py
wavread.py
wavwrite.py
aiffread.py
aiffwrite.py
auread.py
auwrite.py
...
effects/ Subpackage for sound effects
__init__.py
echo.py
surround.py
reverse.py
...
filters/ Subpackage for filters
__init__.py
equalizer.py
vocoder.py
karaoke.py
...
当您执行 process.py
时,您已经位于映射程序包中。 Python 将遍历 sys.path
中定义的所有路径以查找模块,在本例中仅由 ["standard python path", "Mapper/mapper"]
构成。
在这种情况下,python 不会在这些目录中找到名为 mapper 的模块(您已经在 mapper 模块中)。
适合您的解决方案:
- 使用表示法:
from .binconvert import tocsv
(符合PEP 328)
- 启动前从 1 个目录上移并从
Mapper
目录启动 process.py
- 通过添加
Mapper
path 在启动 process.py
之前更改 PYTHONPATH 环境变量
如果包含 "mapper" 包的目录位置在 sys.path:
中,您可以从 "mapper" 包的任何位置导入(使用 "from mapper.anything import that")
# in process.py
import os, sys
THIS_DIR = os.path.dirname(os.path.abspath(__file__)) # "mapper" dir
MAPPER_ROOT_DIR = os.path.dirname(THIS_DIR) # points to "Mapper" dir
if MAPPER_ROOT_DIR not in sys.path:
sys.path.insert(0, MAPPER_ROOT_DIR)
您可以在出现问题的每个模块中包含此代码段。约定是在 运行 的第一个模块中设置路径(在导入任何 "own" 包之前)。 sys.path 内容在所有 运行 个模块之间共享。
我知道有很多关于这个主题的问题,但我看到的大多数答案都描述了解决问题的复杂方法,在我看来,这些问题应该很简单。这是我的目录结构:
Mapper/
LICENSE.txt
README.txt
setup.py
bin/
# nothing here, yet
mapper/
__init__.py
process.py
where.py
# ...
binconvert/
__init__.py
tocsv.py
todict.py
# ...
我想在所有本地开发的模块上使用绝对路径以减少混淆并避免提到的错误 here。
但是,我遇到了很多问题。当我运行process.py
,其中我import
tocsv.py
这样,
from mapper.binconvert import tocsv
我收到错误:ModuleNotFoundError: No module named 'mapper'
我知道我可以做到 from binconvert import tocsv
,但就像我说的,我正在尝试让我所有本地开发的模块导入都使用绝对路径。
当我尝试像这样导入 where.py
时,我遇到了与之前在 tocsv.py
中相同的错误:
from mapper import where
对于这个,我相信有一些方法可以使用相对 import
的点语法,但同样,我想保持我所有的路径都是绝对的。毕竟,我相信根据 python 文档的 this 段,我应该能够做到这一点:
When packages are structured into subpackages (as with the sound package in the example), you can use absolute imports to refer to submodules of siblings packages. For example, if the module
sound.filters.vocoder
needs to use the echo module in thesound.effects package
, it can use fromsound.effects import echo
.
sound/ Top-level package
__init__.py Initialize the sound package
formats/ Subpackage for file format conversions
__init__.py
wavread.py
wavwrite.py
aiffread.py
aiffwrite.py
auread.py
auwrite.py
...
effects/ Subpackage for sound effects
__init__.py
echo.py
surround.py
reverse.py
...
filters/ Subpackage for filters
__init__.py
equalizer.py
vocoder.py
karaoke.py
...
当您执行 process.py
时,您已经位于映射程序包中。 Python 将遍历 sys.path
中定义的所有路径以查找模块,在本例中仅由 ["standard python path", "Mapper/mapper"]
构成。
在这种情况下,python 不会在这些目录中找到名为 mapper 的模块(您已经在 mapper 模块中)。
适合您的解决方案:
- 使用表示法:
from .binconvert import tocsv
(符合PEP 328) - 启动前从 1 个目录上移并从
Mapper
目录启动process.py
- 通过添加
Mapper
path 在启动
process.py
之前更改 PYTHONPATH 环境变量
如果包含 "mapper" 包的目录位置在 sys.path:
中,您可以从 "mapper" 包的任何位置导入(使用 "from mapper.anything import that")# in process.py
import os, sys
THIS_DIR = os.path.dirname(os.path.abspath(__file__)) # "mapper" dir
MAPPER_ROOT_DIR = os.path.dirname(THIS_DIR) # points to "Mapper" dir
if MAPPER_ROOT_DIR not in sys.path:
sys.path.insert(0, MAPPER_ROOT_DIR)
您可以在出现问题的每个模块中包含此代码段。约定是在 运行 的第一个模块中设置路径(在导入任何 "own" 包之前)。 sys.path 内容在所有 运行 个模块之间共享。