在我们公司,我们正在使用颠覆。我们在使用的不同版本中有不同的python模块(自己的和第三方)。我们开发的各种应用程序对共享模块的版本有各种依赖关系。
一种可能性是使用virtualenv
从本地pypi服务器安装模块。因此,在每次初始结账时,我们都需要创建virtualenv,激活它并从requirements.txt安装相关模块。
缺点:
所以我们想出了另一个解决方案,我问你的意见: 在应用程序的路径中,我们使用svn:externals(aka git submodules)来" link"到指定的模块(从它的发布路径和指定的版本号保持只读),所以模块将被放置在应用程序的路径中。 A"导入mylib"将在python site-packages或virtualenv中安装。这可以扩展到甚至将wx,numpy和其他常用库的版本放入我们的存储库并在本地链接它们。
优点是:
实际问题是: 是否有使用此方案的github / sorceforge上的项目?为什么每个人都使用virtualenv而不是这个(看似)更简单的方案? 我从未见过这样的解决方案,所以也许我们错过了一个观点?
PS:我已经在pypa-dev邮件列表上发布了这个,但它似乎是这类问题的错误位置。请原谅这个十字架。
答案 0 :(得分:5)
在应用程序的路径中,我们使用svn:externals(aka git submodules)来" link"到指定的模块(从它的发布路径和指定的版本号保持只读),所以模块将被放置在应用程序的路径中。
这是一种更传统的管理包依赖关系的方法,并且只在内部使用的软件的两个选项中更简单。关于......
初次结帐后,您已准备好运行
......这并不完全正确。如果您的某个依赖项是用C编写的Python库,则需要先编译它。
我们尝试使用git的子模块功能,但无法获取存储库的子路径(如
/source/lib
)
如果您在PYTHONPATH
之外的位置检出整个存储库,然后只是符号链接到PYTHONPATH
内的所需文件或目录,这很容易解决,尽管它确实需要您使用支持符号链接的文件系统。
例如,使用类似......
的布局myproject
|- bin
| |- myprogram.py
|
|- lib
| |- mymodule.py
| |- mypackage
| | |- __init__.py
| |
| |- foopackage -> ../submodules/libfoo/lib/foopackage
| |- barmodule
| |- __init__.py -> ../../submodules/libbar/lib/barmodule.py
|
|- submodules
|- libfoo
| |- bin
| |- lib
| |- foopackage
| |- __init__.py
|
|- libbar
|- bin
|- lib
| barmodule.py
...您的my_project/lib
只需要PYTHONPATH
,所有内容都应该正确导入。
使用此方案在github / sourceforge上有项目吗?
子模块信息只存储在名为.gitmodules
的文件中,快速Google for "site:github.com .gitmodules"会返回相当多的结果。
为什么每个人都使用virtualenv而不是这个(貌似)更简单的方案?
对于在PyPI上发布并随pip
一起安装的软件包,从依赖关系管理的角度来看,它可以说更容易。
如果您的软件具有相对简单的依赖图,例如......
myproject
|- libfoo
|- libbar
......这没什么大不了的,但是当它变得更像......时,
myproject
|- libfoo
| |- libsubfoo
| |- libsubsubfoo
| |- libsubsubsubfoo
| |- libsubsubsubsubfoo
|- libbar
|- libsubbar1
|- libsubbar2
|- libsubbar3
|- libsubbar4
...如果您因任何原因需要升级libbar
,您可能不想负责确定所有这些子包兼容的版本。您可以将该职责委托给libbar
包的维护者。
在您的特定情况下,决定您的解决方案是否正确将取决于问题的答案: -
svn
存储库?svn:externals
来包含它们所需的任何依赖项的兼容版本,如果没有,您是否准备承担自己管理这些依赖项的责任?如果这两个问题的答案都是"是",那么您的解决方案可能适合您的情况。