当前位置: 首页 > 知识库问答 >
问题:

如何用依赖关系维护python应用,包括我自己定制的库?

邢凌
2023-03-14

我正在使用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 方库,我想确保每个人都使用这些库的相同版本。

现在,我遇到了两个关键问题:

  1. 如何从(应用程序)引用(库)?
  2. 如何管理第三方依赖关系?

第一个问题是许多Python开发人员非常熟悉的,并且被多次问到:指示Python从....\库”。我测试了几种不同的方法,但似乎python不愿意在任何地方搜索包,而是在标准库位置或脚本本身的文件夹中。

  • 相对导入不起作用,因为脚本不是库的一部分(即使它是,当脚本直接执行时,这仍然不起作用,除非它被放置在我想避免的“根”项目文件夹中)
  • 将.pth文件(正如阅读本文档时可能想到的那样)放置到脚本文件夹显然没有任何效果

当然,直接干预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中添加了一个新的第三方模块,其他人在更新应用程序后就开始看到导入问题。开发的几个分支,用户安装pip的不同时刻,很少回滚,每个人最终都会使用不同版本的第三方模块。在我的例子中,由于许多开发人员在使用旧的Python2.x代码时大量工作,而我想继续使用Python3.x,所以事情变得更加复杂

在为我的问题寻找可能的解决方案时,我在Python中发现了一个真正优秀的虚拟环境特性。事情看起来很光明:

    < li >为我的项目创建venv < li >分发Requirements.txt文件作为应用程序的一部分,并提供相应填充venv的脚本 < li >将我自己的库符号链接到venv site_packages文件夹,以便Python始终可以检测到它

这个解决方案看起来很自然

所以我想问一个问题。

    < li >有没有办法将特定的python venv绑定到特定的文件夹,以便python launcher自动将该venv用于这些文件夹中的脚本? < li >有没有更好的替代方法来处理我错过的这种情况?

我的项目环境是运行在Windows 10上的Python 3.6。

共有1个答案

方季同
2023-03-14

我想我终于找到了一个合理的答案。只需在 venv 中添加指向 python 解释器的 shebang 行就足够了,例如

#!../../venv/Scripts/python

完整的项目结构将如下所示

myproject
    apps
        main_apps
            app1.py (with shebang)
            app2.py (with shebang)
            ...
        utils
            util1.py (with shebang)
            util2.py (with shebang)
            ...
    library
        __init__.py
        submodule1
            __init__.py
            file1.py
            ...
        submodule2
            ...
    venv
        (python interpreter, 3rd party modules)
        (symlink to library)
    requirements.txt
    init_environment.bat

事情是这样的:

  1. venv是一个虚拟python环境,包含项目所需的一切
  2. 初始化环境。bat是一个根据需求填充venv的脚本。txt,并将指向我的库的符号链接放入venv站点模块
  3. 所有脚本都以指向venv解释器的shebang行(带有相对路径)开始

有一个完整的自定义环境,包含所有库,包括我自己的库,使用它的脚本都会有非常自然的导入。Python启动器还将自动选择Python3.6作为解释器

欺骗:

  1. 如果从其他文件夹调用脚本,相对的sheang将不起作用
  2. 用户仍然需要手动运行init_environment.bat根据requirements.txt更新虚拟环境
  3. Windows上的init_environment脚本需要提升权限来创建符号链接(但希望奇怪的MS决定将在4月17日即将到来的Win10更新中得到修复)

然而,我可以忍受这些限制。希望这对其他寻找类似问题的人有所帮助。

还是很高兴听到其他选项(作为答案)和批评者(作为评论)。

 类似资料:
  • 问题内容: 我想分析Python包的依赖树。我如何获得这些数据? 我已经知道的事情 有时包含一个列出软件包依赖关系的字段 PyPi是Python软件包的在线存储库 PyPi有一个API 我不知道的事情 PyPi上很少有项目(大约10%)在该字段中明确列出依赖项,但仍设法下载正确的软件包。我想念什么?例如,对于统计计算的通俗图书馆,,不会列出,但仍设法安装,等....有没有一种更好的方式自动收集依赖

  • 我有一个简单的maven插件,它依赖于父pom文件。父pom文件有十个(10个)第三方jar依赖项,这些依赖项已经使用以下命令安装在我的本地回购中。 类似地,我已经安装了所有其他9个罐子到我的本地回购。这是uber pom.xml文件。 我也尝试使用uber-pom作为一个插件依赖,因为我是绝望的。有什么想法吗?

  • 依赖关系会迅速变得复杂起来,并且很容易形成 循环依赖(circular dependency) (即 A 依赖 B,B 又依赖 A),这将导致 Puppet 发生错误并停止工作。 幸运的是, Puppet 的 --graph 选项可以很容易生成一个资源之间的依赖关系图, 它可以帮助我们解决循环依赖的问题。 准备工作 使用如下命令安装查看图片文件所需的 graphviz 软件包: # apt-get

  • 我正在使用一个库,它提供了一个c可执行文件的python包装器。 我安装它(https://github.com/bulletphysics/bullet3)使用venv(https://docs.python.org/3/library/venv.html)-一切都很好。 我正在考虑尝试构建 https://github.com/bulletphysics/bullet3 从venv文件夹的根目

  • 问题内容: 我已经在互联网上搜索了很长一段时间,但无法弄清楚如何配置Maven-war插件或类似的东西,以便系统依赖项包含在内置战争中(WEB-INF / lib文件夹) 在jar-build的情况下,我使用maven依赖插件: 但是我不明白在打仗的情况下该怎么办。我试过使用maven-war插件,但是在构建中不包括系统依赖项。 [更新] 我有以下类型的行为: 在我的POM中,构建战争时,这些依赖