首页 > 解决方案 > 被迫在python中导入相对于main.py的文件

问题描述

我已经阅读了几个关于此的链接,但无法找到可以解决我的情况的内容。

这是我的目录结构:

- app

  - __init.py
  - main.py

  - foo
    - __init.py
    - foo_library.py

  - bar
    - __init.py
    -  bar_library.py

我的应用程序启动,main.py然后导入/调用所有其他文件。

但是,似乎我必须导入所有与main.py.

比如里面foo/foo_library,如果我要导入bar/bar_library,那我就做不到from ..bar import bar_library,或者import app.bar.bar_library

相反,我必须这样做import bar.bar_library.py- 即如果我从而main.py不是从foo/foo_library.py.

有什么方法可以使用import app.bar.bar_libraryfrom ..bar import bar_library吗?

标签: python

解决方案


相对导入仅适用于单个包。在您的示例中,您有一个app带有子包foobar. 只要一个脚本或模块导入app(例如,import app),那么模块在foo并且bar可以做相对导入。

脚本不在包中。这与通常用于可执行文件的模型相同,其中操作系统的任务是在公共 LIB 目录中查找静态动态库。所以main.pyapp包没有固有的知识。

当 python 运行脚本时,它会添加其路径,sys.path以便可以导入该路径中的任何模块或目录。在你的情况下,main.py可以import fooimport bar。但是如果你这样做,foo并且bar是单独的包和相对导入将在它们之间不起作用。

您可以通过上移一个目录来解决问题,main.py以便它可以导入app. 更一般地,您可以移动main.py到源代码树中的脚本目录并将您的包 + 脚本包装到可安装的发行版中。

使软件包可安装时,另一个流行的选择是将入口点声明添加到setup.py. 安装程序将在操作系统路径中添加小的虚拟文件,这些文件本质上是python3 -m app.main为了在包中运行模块。通过这种方式,main.py 是包的一部分,可以进行相对导入。


推荐阅读