Python 3:将子包导入顶级包时出现问题

时间:2019-04-18 14:38:43

标签: python python-3.x

我不知道缺少什么,但是我具有以下项目结构:

Project
|audio_input
|output_files
|audio_classifier
||________________
                 |__init__.py
                 |base.py
                 |preprocessing
                 ||_____________
                                |__init__.py
                                |base.py
                                |input_preparation.py
                                |_feature_extraction.py
                 |classification
                 |______________
                                |__init__.py
                                |classifier_gpu_enabled.py
                                |_nn_architectures.py   
|docs
|examples
|tests
|README
|req.txt
|setup.py

audio_classifier是我的源代码根,而base.py的内容是:

import sys
import os

print(sys.path)
print(__name__, __package__)

from audio_classifier.preprocessing.input_preparation import InputPreparation

我有两种情况:

  1. 绝对导入:当我在audio_classifier文件夹中运行python -m base时,出现以下错误: ModuleNotFoundError: No module named 'audio_classifier' 但这确实使我感到困惑,因为我在顶层软件包中已经有一个__init__.py。不应该被认可吗?

sys.path包含路径['/ home / $ USER / Project / audio_classifier',...],那么它不应该使用绝对导入吗? 实际上__package__是空的。

  1. 相对导入:现在将from audio_classifier.preprocessing.input_preparation import InputPreparation的{​​{1}}替换为from .preprocessing.input_preparation import InputPreparation

ImportError: attempted relative import with no known parent package 这与python无法将我的顶级软件包标识为软件包的问题根源相同。

注意:使用PyCharm运行base.py时,第一个选项实际上有效。但是源根,环境和路径与我在终端上运行的相同。我肯定在这里错过了一些非常重要的东西。

我试图了解numpy和librosa这样的大型库是如何组织其存储库的,并试图将此概念引入我自己的存储库中,但是复制它们的方法会给我带来这些错误,而我确实无法解决这些错误片刻。

伙计,谢谢你。

EDIT1: PYTHONPATH: ['', '$HOME/.conda/envs/ac/lib/python37.zip', '$HOME/.conda/envs/ac/lib/python3.7', '$HOME/.conda/envs/ac/lib/python3.7/lib-dynload', '$HOME/.conda/envs/ac/lib/python3.7/site-packages']

1 个答案:

答案 0 :(得分:0)

  • 您的“源根目录”(以PyCharm术语)应位于setup.py等文件所在的位置(即,图中的Project/)。这是您放置所有包裹的地方。 (有些存储库有一个附加的src/目录,但现在就不要考虑了。)
  • 如果您希望能够轻松使用Project/audio_classifier导入内容,则
  • sys.path应该from audio_classifier...中。仅Project

这是一个简单的例子:

$ mkdir ac  # create a package directory
$ touch ac/__init__.py  # create the package init file so it's a package
$ echo 'from .foo import baz' > ac/base.py  # create a module in the package
$ mkdir ac/foo  # create a subpackage
$ echo 'baz = 8' > ac/foo/__init__.py  # create a package init file in the subpackage
$ echo -e 'from .base import baz\nprint(baz)' > ac/__main__.py  # create a __main__ file that can be run with `-m`
$ python -m ac
8
$

结构看起来像

$ tree -I '*.pyc'
.
└── ac
    ├── __init__.py
    ├── __main__.py
    ├── base.py
    └── foo
        └── __init__.py

事物也可以交互地工作:

>>> import ac
>>> import ac.base
>>> import ac.foo as f
>>> f.baz
8
>>> ac.base.baz
8