【发布时间】:2017-07-26 14:18:18
【问题描述】:
我正在使用 Python 开发一些特定于公司的应用程序。有一个自定义共享模块(“库”)描述了一些数据和算法,并且有几十个 Python 脚本可以使用这个库。这些文件很多,所以它们被组织在子文件夹中
myproject
apps
main_apps
app1.py
app2.py
...
utils
util1.py
util2.py
...
library
__init__.py
submodule1
__init__.py
file1.py
...
submodule2
...
用户想要运行这些脚本,只需转到 myproject\utils 并启动“py util2.py some_params”即可。这些用户中有许多是开发人员,因此他们经常想要编辑库并立即使用更新的代码重新运行脚本。该项目还使用了一些 3rd 方库,我想确保每个人都使用这些库的相同版本。
现在,我遇到了两个关键问题:
- 如何从(应用)引用(库)?
- 如何管理第 3 方依赖项?
第一个问题对于很多 Python 开发者来说都很熟悉,并且在 SO 上被问过很多次:指示 Python 从 "....\library" 导入包是相当困难的。我测试了几种不同的方法,但似乎 python 不愿意在任何地方搜索包,而是在标准库位置或脚本本身的文件夹中。
- 相对导入不起作用,因为脚本不是库的一部分(即使它是,当脚本直接执行时这仍然不起作用,除非它放在我想要的“根”项目文件夹中喜欢避免)
- 将 .pth 文件(从阅读 this document 可能会想到)到脚本文件夹显然没有任何效果
当然直接干预 sys.path 的工作,但是像这样的样板代码在每个脚本文件中看起来都很糟糕
import sys, os.path
here = os.path.dirname(os.path.realpath(__file__))
module_root = os.path.abspath(os.path.join(here, '../..'))
sys.path.append(python_root)
import my_library
我意识到发生这种情况是因为 Python 希望正确“安装”我的库,如果这个库与使用它的脚本分开开发,那确实是唯一正确的方法。但不幸的是,情况并非如此,我认为每次更改库时都重新“安装”库将非常不方便并且容易出错。
第二个问题很简单。有人在我们的 app/lib 中添加了一个新的 3rd 方模块,其他人在更新他们的应用程序后开始看到导入问题。几个开发分支,用户执行 pip 安装的不同时刻,很少回滚 - 每个人最终都会使用不同版本的 3rd 方模块。就我而言,由于许多开发人员大量使用较旧的 Python 2.x 代码,而我想继续使用 Python 3.x,因此事情变得更加复杂
在为我的问题寻找可能的解决方案时,我发现 Python 中有一个非常出色的虚拟环境功能。事情看起来很光明:
- 为我的项目创建一个 venv
- 将 Requirements.txt 文件作为应用程序的一部分分发,并提供一个相应地填充 venv 的脚本
- 将我自己的库符号链接到 venv site_packages 文件夹,以便 Python 始终检测到它
这个解决方案看起来非常自然和强大。我明确地为我的项目设置了我自己的环境,并将我需要的任何东西放入这个 venv,包括我自己的库,我仍然可以在运行中进行编辑。它确实有效。但是调用 activate.bat 来激活这个 python 环境和另一个批处理文件来停用它是一团糟,尤其是在 Windows 平台上。正在编辑 sys.path 的样板代码看起来很糟糕,但至少它不会像这个潜在的修复那样干扰用户体验。
所以我想问一个问题。
- 有没有办法将特定的 python venv 绑定到特定的文件夹,这样 python 启动器会自动将此 venv 用于这些文件夹中的脚本?
- 是否有更好的替代方法来处理我错过的这种情况?
我的项目环境是在 Windows 10 上运行的 Python 3.6。
【问题讨论】:
-
您是否使用
setuptools.py来“安装”?如果是这样,您可以使用develop命令行参数代替install,请参阅讨论here。这使您可以在库上工作并立即查看所做的更改。 -
不幸的是,据我所知,对您有帮助的工具在 Windows 上并不真正可用。例如,您可以尝试寻找
autoenv的等价物 -
谢谢!这是一个很好的选择,我完全错过了。现在在我的项目中没有“安装”过程,脚本只是通过修改后的 sys.path 查找模块。我更喜欢使用 PIP 而不是 setuptools.py,但它有一个类似的选项 (
pip install -e),这是使用我的自定义库与符号链接选项来初始化环境(虚拟或非虚拟)的更好方法。这样,在许多情况下,完全没有任何虚拟环境也可能是可以的(尽管我更喜欢保留一个以便更容易控制依赖关系) -
不幸的是,Windows 平台上的
develop选项似乎破坏了某些东西。安装程序显然是成功的,一个“library.egg-link”文件出现在 venv 的站点包中,但 Python 无法解决它(参见类似问题 stackoverflow.com/questions/10569846/…)。另一方面,在同一位置手动创建符号链接就可以了。 -
那很不幸。就像我说的那样,我的印象是,很多工具并不是以 Windows 为重点开发的,而是事后才想到的。
标签: python windows python-3.x packaging python-venv