Python:在import语句中无法识别的父包的名称

时间:2017-09-08 07:52:10

标签: python python-3.x import package python-import

我知道关于这个主题有很多问题,但我看到的大多数答案都描述了对我看来应该很简单的问题的复杂解决方法。这是我的目录结构:

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,但就像我说的那样,我试图让我所有本地开发的模块导入使用绝对路径。

当我尝试导入tocsv.py时,我在where.py中收到与以前相同的错误:

 from mapper import where

对于这个,我相信有一些方法可以使用相对import的点语法,但同样,我想保留所有路径的绝对值。毕竟,我相信根据this通过python文档,我应该能够做到这一点:

  

当包被组织成子包时(与示例中的声音包一样),您可以使用绝对导入来引用兄弟包的子模块。例如,如果模块sound.filters.vocoder需要使用sound.effects package中的echo模块,则可以使用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
              ...

2 个答案:

答案 0 :(得分:3)

执行process.py时,您已经位于映射器包中。 Python将查看sys.path中定义的所有路径以查找模块,在这种情况下,模块仅由["standard python path", "Mapper/mapper"]组成。

在这种情况下,python将无法在这些目录中找到名为mapper的模块(您已经在映射器模块中)。

您的解决方案:

  1. 使用符号:from .binconvert import tocsv(符合PEP 328
  2. 在开始之前从1个目录上移,并从process.py目录
  3. 启动Mapper
  4. 通过添加process.py路径
  5. 启动Mapper之前更改PYTHONPATH环境变量

答案 1 :(得分:-1)

如果包含“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)

您可以在问题发生的每个模块中包含此代码段。惯例是在正在运行的第一个模块中设置路径(在导入任何“自己的”包之前)。 sys.path内容在所有运行的模块之间共享。