【问题标题】:Python package structurePython包结构
【发布时间】:2011-04-21 17:24:06
【问题描述】:

我有一个包含多个子包的 Python 包。

myproject/
  __init__.py
  models/
    __init__.py
    ...
  controllers/
    __init__.py
    ..
  scripts/
    __init__.py
    myscript.py

在 myproject.scripts.myscript 中,如何访问 myproject.models?我试过了

from myproject import models # No module named myproject
import models # No module named models
from .. import models # Attempted relative import in non-package

我以前必须解决这个问题,但我不记得应该怎么做。这对我来说并不直观。

【问题讨论】:

  • myscript.py 的运行情况如何?你能告诉我们你的命令行吗?这将对答案产生影响。
  • 试试import myproject.models
  • 好的,我找到了解决方案:导入前sys.path.append(os.path.dirname(os.path.dirname(__file__)))。不过我希望有更好的解决方案。
  • 这可能与你的pythonpath有关。你想从哪里导入这个包?如果它与包不在同一位置,则必须将其添加到 pythonpath。
  • Brandon Craig Rhodes:我在 myproject/ 目录中,正在运行 python scripts/myscript.py

标签: python packages


【解决方案1】:

这是正确的版本:

from myproject import models

如果使用ImportError: No module named foo 失败,那是因为您没有设置PYTHONPATH 以包含包含myproject/ 的目录。

恐怕其他人会提出技巧让您避免设置PYTHONPATH。我敦促你无视他们。这就是 PYTHONPATH 存在的原因:告诉 Python 在哪里寻找要加载的代码。它是健壮的、合理的、有据可查的,并且可移植到许多环境中。人们为了避免设置它而玩的把戏都不是这些东西。

即使没有设置PYTHONPATH,显式相对导入工作,因为它可以向上遍历目录层次结构,直到找到正确的位置,它不会'不需要找到顶部然后向下走。但是,它在作为命令行参数传递给python 的脚本中不起作用(或者等效地,直接使用#!/usr/bin/python 行调用)。这是因为在这两种情况下,它都成为进程的__main__ 模块。从__main__ 无处可走——它已经在顶部了!如果您通过 importing 该模块调用脚本中的代码,那么就可以了。也就是比较:

python myproject/scripts/myscript.py

python -c 'import myproject.scripts.myscript'

您可以利用这一点,不直接执行脚本模块,而是创建一个 bin/myscript 来执行导入并可能调用一个 main 函数:

import myprojects.scripts.myscript
myprojects.scripts.myscript.main()

对比 Twisted 的命令行脚本是如何定义的:http://twistedmatrix.com/trac/browser/trunk/bin/twistd

【讨论】:

  • 谢谢。你能解释一下为什么from .. import models 不起作用吗?我认为相对导入将允许您在不设置 PYTHONPATH 的情况下执行此操作。
  • 谢谢,让-保罗!我喜欢这种方法。
【解决方案2】:

您的项目不在您的路径中。

选项 A

  • 安装你的包,以便 python 可以在任何地方通过它的绝对名称找到它(使用from myproject import models

选项 B

  • 将相对父级添加到路径中的技巧
  • sys.path.append(os.path.abspath('..'))

推荐前一个选项。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-04-13
    • 2021-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多