繁体   English   中英

如何维护带有依赖项的python应用程序,包括我自己的自定义库?

[英]How to maintain python application with dependencies, including my own custom libs?

我正在使用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”。 其中许多用户都是开发人员,因此他们经常想要编辑库并立即使用更新的代码重新运行脚本。 此项目还使用了一些第三方库,我想确保每个人都使用这些库的相同版本。

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

  1. 如何从(apps)引用(库)?
  2. 如何管理第三方依赖?

第一个问题对于许多Python开发人员来说是很熟悉的,并且在SO上被多次询问:指示Python从“.... \\ library”导入包很困难。 我测试了几种不同的方法,但似乎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安装的不同时刻,很少回滚 - 每个人最终都会使用不同版本的第三方模块。 在我的情况下,由于许多开发人员使用较旧的Python 2.x代码工作很多,而我还想继续使用Python 3.x,事情变得更加复杂。

在为我的问题寻找可能的解决方案时,我在Python中发现了一个非常出色的虚拟环境功能。 事情看起来很光明:

  1. 为myproject创建一个venv
  2. 将Requirements.txt文件分发为app的一部分,并提供相应填充venv的脚本
  3. 将我自己的库符号链接到venv site_packages文件夹,这样它就会被Python检测到

这个解决方案看起来非常自然和强大 我明确地为我的项目设置了自己的环境,并将我需要的任何内容放入这个venv中,包括我自己的lib,我仍然可以动态编辑。 它确实有效。 to make this python environment active and another batch file to deactivate it is a mess, especially on Windows platform. 但调用使这个python环境处于活动状态,另一个批处理文件停用它是一个烂摊子,特别是在Windows平台上。 编辑sys.path的Boilerplate代码看起来很糟糕,但至少它不像这个潜在的修复那样干扰UX。

所以我想问一个问题。

  1. 有没有办法将特定的python venv绑定到特定文件夹,以便python启动器会自动将这个venv用于这些文件夹中的脚本?
  2. 有没有更好的替代方法来处理我错过的这种情况?

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

我想我终于找到了合理的答案。 只需在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. init_environment.bat是一个根据requirements.txt填充venv的脚本,并将一个符号链接到我的库中,进入venv站点模块
  3. 所有脚本都以shebang行指向(相对路径)到venv解释器

有一个完整的自定义环境,包括我自己的所有库和使用它的脚本都将具有非常自然的导入。 Python启动器还将自动选择Python 3.6作为解释器,并在从控制台或Windows资源管理器启动项目中的任何面向用户的脚本时加载相关模块。

缺点:

  1. 如果从其他文件夹调用脚本,则相对shebang将无法工作
  2. 用户仍然必须根据requirements.txt手动运行init_environment.bat来更新虚拟环境
  3. Windows上的init_environment脚本需要提升权限才能生成符号链接(但希望奇怪的MS决定将在2017年4月即将推出的Win10更新中修复)

但是,我可以忍受这些限制。 希望这会帮助其他人寻找类似的问题。

仍然很高兴仍然听到其他选项(作为答案)和评论家(作为评论)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM