Python包结构

2024-04-23 11:23:43 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个带有几个子包的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

我以前不得不解决这个问题,但我永远记不起该怎么做。对我来说这不是直觉。


Tags: noinfrompyimportinitmodelsmyproject
2条回答

你的项目不在你的轨道上。

方案A

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

方案B

  • 在你的路径中添加亲生父母的诡计
  • sys.path.append(os.path.abspath('..'))

建议使用前一个选项。

这是正确的版本:

from myproject import models

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

恐怕其他人会建议一些技巧,让您避免设置PYTHONPATH。我劝你不要理会他们。这就是PYTHONPATH存在的原因:告诉Python在哪里查找要加载的代码。它是健壮的,有相当好的文档记录,并且可以移植到许多环境中。人们为了避免设置而玩的把戏不属于这些。

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

python myproject/scripts/myscript.py

python -c 'import myproject.scripts.myscript'

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

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

与Twisted的命令行脚本的定义相比:http://twistedmatrix.com/trac/browser/trunk/bin/twistd

相关问题 更多 >