【问题标题】:Having Trouble with Import Statement in PythonPython 中的 Import 语句有问题
【发布时间】:2017-05-23 06:07:26
【问题描述】:

我目前的项目结构是这样的。

python/
    __init__.py
    project_1/
        __init__.py
        program_1.py
    project_2/
        __init__.py
        program_2.py
    project_3/
        __init__.py
        program_3.py

我想从 project_1/program_1.py 和 project_2/program_2.py 中导入一个名为 INFO 的类 project_3/program_3.py。在我的 program_1.py 和 program_2.py 中,我尝试了以下无效的导入语句。

编辑 - 我通常“cd”到 project_1 并从那里运行我的 program_1.py。

from project_3.program_3 import INFO

Traceback (most recent call last):
  File "./program_1.py", line 43, in <module>
    from project_3.program_3 import INFO
ImportError: No module named 'project_3'

from python.project_3.program_3 import INFO

Traceback (most recent call last):
  File "./program_1.py", line 43, in <module>
    from python.project_3.program_3 import INFO
ImportError: No module named 'python'

我将类 INFO 导入 program_1.py 和 program_2.py 的唯一方法是将 program_3.py 复制到 program_1 和 program_2 的文件夹中。我在 program_1 和 program_2 的语句中的导入将变为:

python/
    __init__.py
    project_1/
        __init__.py
        program_1.py
        program_3.py
    project_2/
        __init__.py
        program_2.py
        program_3.py
    project_3/
        __init__.py
        program_3.py

from program_3 import INFO

这很不方便,因为现在我必须在所有 3 个位置更新 program_3.py。假设我构建项目文件夹的方式有问题:

  • 构建文件夹以便我可以从 program_1/2.py 调用 program_3.py 的正确/最佳方法是什么?
  • 如果我当前的结构没有问题,如何将 INFO 类正确导入 program_1/2.py?

我已经阅读了python documentation,但它没有说明将类从一个子文件夹导入另一个子文件夹。我还查看了来自 Stack Overflow 的另一个 post,但它与我的结构不同。

更新 1 - 请务必注意,我只是使用 project_1/2 作为文件夹来组织我的项目。我最初在所有文件夹中都有 init.py,因为我不知道自己在做什么。我想在 project_1/program_1.py 中导入的唯一模块/包来自 project_3/program_3.py。示例:

python/
    project_1/
        program_1.py
    project_2/
        program_2.py
    project_3/
        __init__.py
        program_3.py

【问题讨论】:

  • 将每个python脚本中的目录更改为python根目录os.chdir('./python'),然后从那里处理导入

标签: python python-3.x import


【解决方案1】:

使用子模块时,需要使用相对导入。在提供的示例中,从program_1 导入program_3 应该是:

from ..project_3 import program_3

然后您可以使用INFO 类:program_3.INFO

如果您的可执行文件位于脚本之外,则此方法有效,即示例中使用模块 python 的文件应位于 python 模块之外。

如果 python 包的一部分作为脚本执行,则应将 -m 选项传递给解释器:

python3 -m python.project_1.program_1

我希望这会有所帮助。

【讨论】:

  • 我通过“from ..project_3.program_3 import INFO”做了一些不同但相似的事情。我得到的错误是“SystemError: Parent module '' not loaded, cannot perform relative import.”
  • 您正在运行的文件是否在模块本身内部?如果是这种情况,请使用-m 选项,例如python -m python.project_1.program_1
  • 我通常 cd 进入 project_1 并从那里运行 ./program_1.py。如果我尝试使用 -m 选项运行它,我会收到以下错误:python3.5 -m python.project_1.program_1.py /usr/local/bin/python3.5: Error while find spec for 'python.project_1 .program_1.py' (ImportError: No module named 'python')
  • 您需要cd到包含外部模块python的目录,然后您可以按照更新的答案运行您的程序。如果您真的想从 program_1 中运行它,则需要从程序中更改路径或类似的东西...
  • @dreamzboy 一般来说,直接从包内(包含__init__.py 的文件夹)执行代码是错误的,很可能会导致问题。
【解决方案2】:

以前的解决方案给我同样的错误。

我使用 sys: 找到了解决方法:

import sys
sys.path.append('../')

from project_3 import program_3
...

这样,您将“python”文件夹设置为参考(在您的情况下,它是父文件夹,但您可以选择所需的路径)

希望对你有帮助

【讨论】:

  • 我已经更新了我的答案,以便在模块内运行脚本时它可以工作。
  • 谢谢。这可行,但 PEP8 当然不喜欢 import 语句位于 sys.path.append ('../') 语句下方的事实。这绝对比我的工作要好,但如果有替代方案,我更喜欢遵循“标准”以保持整洁。
  • 不幸的是,这是我在其他论坛上找到的唯一解决方案。它们提供了更优雅的方式来定义路径,但它是相同的修复。如果您有其他解决方案,请分享(我也有兴趣:))
  • 我最终做了解决方法,将我的 program_1/2.py 移动到 python/ 目录下,并且能够使用 from project_3 import program_3.py 没有错误。您的解决方案绝对是聪明的,但在我看来,它更像是一个黑客而不是一个解决方案。如果我有不同版本的program_1,我就把它移回project_1文件夹,在python目录下继续开发原来的program_1。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-02
  • 1970-01-01
  • 1970-01-01
  • 2014-05-05
  • 2014-09-12
  • 2013-06-14
相关资源
最近更新 更多