小编典典

了解Python中的导入链

python

我知道有几个类似的问题,但是我很难理解我在获取和浏览文档时遇到的错误,而类似的问题还没有帮助。如果有的话,类似的问题会让我觉得自己在做的事是对的。

我有以下文件:

src / main.py

from pack import pack

if __name__ == '__main__':
    pack.exec("Hello Universe!")

src / pack / pack.py

import util

def exec(text):
    util.write(text)

if __name__ == '__main__':
    exec("Hello World!")

src / pack / util.py

def write(text):
    print(text)
  • src / pack / _ init _.py *

    EMPTY FILE


当我python pack.pysrc/pack目录运行时,它可以工作(打印“ Hello World!”)。但是,当我python main.pysrc目录运行时,出现以下异常:

Traceback (most recent call last):
  File ".../src/main.py", line 1, in <module>
    from pack import pack
  File ".../src/pack/pack.py", line 1, in <module>
    import util
ImportError: No module named util

如果我改变了进口线pack.py,以from . import util作为建议,有效相反occours。
main.py运行成功,但是现在pack.py失败,引发:

Traceback (most recent call last):
  File ".../src/pack/pack.py", line 1, in <module>
    from . import util
ValueError: Attempted relative import in non-package

我本以为导入是相对于当前位置的,因此您应该能够构建这样的导入链。对我来说,模块应该根据程序的开始位置不同地导入同级文件对我来说似乎很奇怪。

有人可以解释为什么此错误以一种方式而不是另一种方式发生,以及是否有某种方法允许此文件结构运行,无论我想从main.py还是从中运行pack.py


阅读 273

收藏
2021-01-20

共1个答案

小编典典

在两种情况下,您都将无法使导入工作。这是因为在一种情况下,您将pack.py作为主文件运行,而在另一种情况下,您将其作为软件包的一部分运行。

当您将其作为独立脚本运行时python pack.py,“
pack”目录将添加到PYTHONPATH中,这意味着您可以导入其中的任何模块。因此,import util将工作。

运行时python main.py,将src目录添加到PYTHONPATH中。这意味着目录中的任何模块或软件包(src例如pack目录)现在都可以导入。因此from pack import pack。但是,util.py现在您需要访问from pack import util。正如您所注意到的,您也可以from . import util从内部执行操作pack.py

但是,您不能同时真正做到两者。要么src/是主目录,要么src/pack是。

一个明显但错误的解决方案是让main.py将src/pack目录添加到PYTHONPATH中。那会起作用,但这不是一个好主意。正确的方法是下定决心。是src/pack应该通过导入模块,import pack还是仅仅是带有一堆Python脚本的文件夹?决定!:-)

我认为在这种情况下,显然src/pack应该将其作为模块。因此,请像对待模块一样对待它,并确保它像模块一样可用。这样您from pack import util甚至可以在pack.py作为主脚本运行时使用。

你是怎样做的?好吧,基本上,您可以将pack模块安装在站点程序包中,或者将src目录添加到PYTHONPATH中。最后一个就是您在开发过程中想要的。您可以使用手动进行export PYTHONPATH=<path>,也可以让测试运行人员为您完成。您没有测试运行程序?好吧,你应该,但这是另一个问题。:)

要在不再进行开发后永久安装它,请查看Distribute。它包括一个测试运行程序。;)

2021-01-20