阅读 97

Python项目化安装第三方模块的实现方案

之前接触的高级语言对于第三方模块的管理,基本都是项目化安装,到了Python发现pip命令默认都是全局安装。

虽然平常开发和部署都使用Docker,避免了模块冲突、删除等问题,但把第三方模块当全局变量来处理的方式自然不能忍。

网上找了很久资料没有发现靠谱的解决方案,于是从开始了探索。

解决方案

先来回顾一下使用第三方模块的过程,再来针对这些步骤进行必要的修改和调整。

  1. 使用pipy(Python Package Index)安装第三方模块。
  2. 在项目代码中引用模块。
  3. 将依赖的包写成配置文件。

安装

环境变量

要修改第三方模块安装路径,最容易找到的方法就是通过修改环境变量实现。

通过python -m site命令可以打印出配置信息。

显示的默认安装路径是/usr/local/lib/python3.7/site-packages,支持通过修改USER_BASEUSER_SITE参数进行自定义安装路径。

但这显然不是我们想要到,因为没有解决根本问题!

只是把全局安装的路径替换了而已,比较适用于解决磁盘空间不足的问题。

并没实现项目化安装,毕竟不可能每次安装之前都改一下环境变量~

即使不怕麻烦如此操作,每个项目都修改环境变量的话,如果同时修改也会引起问题。

命令参数

所以我们需要换一种更友好的方式,比如看一看pip命令在安装模块的时候是不是可以指定目录。 pip install -h后在一大堆参数说明中发现有个-t参数可以指定安装目录。

比如说希望将第三方模块flask安装到项目根路径的package目录下,可以执行这样一条命令:

pip install -t ./package flask

引用

由于改变了第三方模块安装路径,所以不能从默认的全局路径引用了,需要采用引用自定义包的方式。

Python的引用机制不像 Node.js 可以直接使用相对路径,需要通过sys.path.append函数将包的根路径添加到系统变量中。 然后才可以通过 import 引用了。

示例代码:

import os,sys
fullpath = os.path.abspath(__file__)
path = fullpath.replace('src/' + __name__.replace('__', '')+'.py', '')
sys.path.append(path + 'package')
from flask import Flask
...
复制代码

配置

默认的依赖导出命令是pip freeze,但是这个命令很不友好,会列出所有全局安装的模块。

所以找到了替代方案pipreqs,它会自动遍历代码,找到第三方模块引用并生成配置文件,比较智能,但是不知道在大型项目上会不会有性能问题。

使用时需要先通过pip install pipreqs安装,然后在项目目录下执行pipreqs ./,会自动生成requiements.txt文件,如果文件存在则需要添加--force参数来允许覆盖。

不过有个需要注意的地方就是:如果引用的自定义模块与第三方模块重名,就会被pipreqs解析为第三方模块。

所以在命名自定义模块的时候尽量加上前缀避免重名。

其它方案

写完文章之后发现还有另一种实现方式,就是使用第三方工具virtualenvvirtualenvwrapper,基本原理就是临时修改环境变量,有兴趣的读者可以试一试。


原文链接:tech.gtxlab.com/python-pack…

作者信息:朱德龙,人和未来高级前端工程师。

关注下面的标签,发现更多相似文章
评论