在复杂 Python 项目中处理导入的正确方法是什么?
Which is the correct way of handling imports in complex Python project?
我一直将 Python 用于单文件脚本,现在我正在处理我的第一个 "complex" 项目,所以我没有使用 Python 中的包的经验(3.x).
我知道这是一个常见问题,但我缺少在我的项目中成功组织模块导入的一些东西,应该用作库。
假设以下项目树:
myProject/
- subpackage1/
- __init__.py
- other1.py
- subpackage2/
- __init__.py
- other2.py
- __init__.py
- foo.py
- bar.py
相互导入模块的正确方法是什么? 特别是:
- 从
bar
导入 foo
- 从
other1
导入 foo
- 从
other2
导入 other1
- 在开发过程中从不同的目录导入
foo
(这是一个库)(虚拟环境是正确的选择吗?)
谢谢!
编辑:(使问题更具体)我在提问之前显然尝试了不同的方法。我在一些流行的项目中看到的是使用像 from myProject.subpackage1.other1 import something
这样的绝对导入。它看起来像是一个干净的解决方案(类似于我以前在 Java 中所做的),但是当采用这种方法时,由于导入错误,我不能简单地 运行 我的代码。 virtualenv
能否成为在尝试导入之前安装软件包的解决方案?
1。从 bar
导入 foo
如the tutorial所说,您可以通过导入from .
从同一目录导入模块。例如:
from . import foo
如果 bar
与 python bar.py
一起执行,那么您也可以完全导入它,就像任何其他模块一样:
import foo
这是有效的,因为已执行文件的父目录已添加到模块搜索路径 (sys.path/PYTHONPATH)。但是,我不会依赖这种行为,因为它对导入模块和主模块意味着不同的东西。
2。从 other1
导入 foo
如果您使用相对导入语法,那么您可以添加另一个 .
来表示父目录:
from .. import foo
3。从 other2
导入 other1
现在这应该不足为奇了,但是您也可以在子包中对模块使用相对导入:
from ..subpackage1 import other1
4。在开发过程中从不同的目录导入 foo
(一个库)
我假设 "a different directory" 是指 "a different project"。在那种情况下,是的,您希望将 foo
打包为 distutils/setuptools 包,然后将其安装到另一个项目的 virtualenv 中。
对于已经很长的 post 来说,具体如何做到这一点有点复杂,但是 setuptools 网站有一个相当不错的 tutorial 可以做到这一点。
我一直将 Python 用于单文件脚本,现在我正在处理我的第一个 "complex" 项目,所以我没有使用 Python 中的包的经验(3.x).
我知道这是一个常见问题,但我缺少在我的项目中成功组织模块导入的一些东西,应该用作库。
假设以下项目树:
myProject/
- subpackage1/
- __init__.py
- other1.py
- subpackage2/
- __init__.py
- other2.py
- __init__.py
- foo.py
- bar.py
相互导入模块的正确方法是什么? 特别是:
- 从
bar
导入 - 从
other1
导入 - 从
other2
导入 - 在开发过程中从不同的目录导入
foo
(这是一个库)(虚拟环境是正确的选择吗?)
foo
foo
other1
谢谢!
编辑:(使问题更具体)我在提问之前显然尝试了不同的方法。我在一些流行的项目中看到的是使用像 from myProject.subpackage1.other1 import something
这样的绝对导入。它看起来像是一个干净的解决方案(类似于我以前在 Java 中所做的),但是当采用这种方法时,由于导入错误,我不能简单地 运行 我的代码。 virtualenv
能否成为在尝试导入之前安装软件包的解决方案?
1。从 bar
导入 foo
如the tutorial所说,您可以通过导入from .
从同一目录导入模块。例如:
from . import foo
如果 bar
与 python bar.py
一起执行,那么您也可以完全导入它,就像任何其他模块一样:
import foo
这是有效的,因为已执行文件的父目录已添加到模块搜索路径 (sys.path/PYTHONPATH)。但是,我不会依赖这种行为,因为它对导入模块和主模块意味着不同的东西。
2。从 other1
导入 foo
如果您使用相对导入语法,那么您可以添加另一个 .
来表示父目录:
from .. import foo
3。从 other2
导入 other1
现在这应该不足为奇了,但是您也可以在子包中对模块使用相对导入:
from ..subpackage1 import other1
4。在开发过程中从不同的目录导入 foo
(一个库)
我假设 "a different directory" 是指 "a different project"。在那种情况下,是的,您希望将 foo
打包为 distutils/setuptools 包,然后将其安装到另一个项目的 virtualenv 中。
对于已经很长的 post 来说,具体如何做到这一点有点复杂,但是 setuptools 网站有一个相当不错的 tutorial 可以做到这一点。