如何管理具有依赖关系的Python应用程序,包括我自己的自定义库?

9 浏览
0 Comments

如何管理具有依赖关系的Python应用程序,包括我自己的自定义库?

我正在使用Python开发一些公司特定的应用程序。有一个自定义的共享模块(\"库\"),描述了一些数据和算法,并且有几十个使用该库的Python脚本。这些文件相当多,所以它们被组织在子文件夹中。\n

myproject
    apps
        main_apps
            app1.py
            app2.py
            ...
        utils
            util1.py
            util2.py
            ...
    library
        __init__.py
        submodule1
            __init__.py
            file1.py
            ...
        submodule2
            ...

\n用户希望通过简单地转到myproject\\utils并启动\"py util2.py some_params\"来运行这些脚本。许多用户都是开发人员,所以他们经常希望编辑库并立即使用更新后的代码重新运行脚本。该项目还使用了一些第三方库,我希望确保每个人都使用相同的库版本。\n现在,我遇到了两个关键问题:\n

  1. 如何从(apps)中引用(library)?
  2. \n

  3. 如何管理第三方依赖项?

\n第一个问题对许多Python开发人员来说非常熟悉,并且在SO上被多次提问:很难指示Python从\"....\\library\"导入包。我测试了几种不同的方法,但似乎Python只在标准库位置或脚本本身的文件夹中搜索包。\n

  • 相对导入不起作用,因为脚本不是库的一部分(即使是,当直接执行脚本时也不起作用,除非将其放在\"root\"项目文件夹中,我希望避免这种情况)
  • \n

  • 将.pth文件(根据阅读这个文档可能会这样认为)放在脚本文件夹中似乎没有任何效果

\n当然,直接干预sys.path是行得通的,但是在每个脚本文件中加入这样的样板代码看起来相当糟糕\n

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

\n我意识到这是因为Python希望我的库被正确地\"安装\",这确实是唯一正确的方法,如果这个库是与使用它的脚本分开开发的话。但不幸的是,这不是我的情况,而且我认为每次更改库都重新\"安装\"将非常不方便且容易出错。\n第二个问题很直观。有人将新的第三方模块添加到我们的应用/库中,其他人在更新应用后开始遇到导入问题。几个开发分支、用户何时进行pip安装、几次回滚 - 最终每个人使用不同版本的第三方模块。在我的情况下,情况更加复杂,因为许多开发人员经常使用旧的Python 2.x代码,而我希望转向Python 3.x。\n在寻找解决方案时,我发现了Python中一个真正出色的虚拟环境功能。事情看起来非常明朗:\n

  1. 为myproject创建一个虚拟环境
  2. \n

  3. 作为应用程序的一部分分发一个Requirements.txt文件,并提供一个脚本根据此文件填充venv
  4. \n

  5. 将自己的库作为符号链接到venv site_packages文件夹中,以便始终被Python检测到

\n这个解决方案看起来非常自然和强大。我明确为我的项目设置了自己的环境,并将所需的一切放入这个venv中,包括我可以随时编辑的自己的库。而且它确实有效。但是,调用\"activate.bat\"来激活此Python环境,再调用另一个批处理文件来停用它在Windows平台上非常混乱。虽然编辑sys.path的样板代码看起来很糟糕,但至少它不会像此潜在的修复方法那样干扰用户体验。\n所以我想问一个问题。\n

  1. 是否有一种方法将特定的Python venv绑定到特定的文件夹,以便Python启动器会自动为这些文件夹中的脚本使用此venv?
  2. \n

  3. 是否有更好的处理这种情况的替代方法我没有注意到的?

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

0
0 Comments

如何维护具有依赖关系的Python应用程序,包括我自己的自定义库?

最近我终于找到了一个合理的答案。只需要在venv中添加指向Python解释器的shebang行即可,例如:

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

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

myproject
    apps
        main_apps
            app1.py(带有shebang)
            app2.py(带有shebang)
            ...
        utils
            util1.py(带有shebang)
            util2.py(带有shebang)
            ...
    library
        __init__.py
        submodule1
            __init__.py
            file1.py
            ...
        submodule2
            ...
    venv
        (Python解释器,第三方模块)
        (指向library的符号链接)
    requirements.txt
    init_environment.bat

工作方式如下:

  1. venv是一个虚拟的Python环境,包含项目所需的一切
  2. init_environment.bat是一个脚本,根据requirements.txt填充venv,并在venv site-modules中放置指向我的库的符号链接
  3. 所有脚本都以shebang行开头,指向(使用相对路径)venv解释器

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

缺点:

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

不过,我可以接受这些限制。希望这对其他遇到类似问题的人有所帮助。

如果还有其他选项(作为答案)或批评意见(作为评论),那将非常好。

0