Python虚拟环境间通用模块的管理方案咨询
在Linux服务器上用Python搭建了多套带独立虚拟环境的项目,为避免代码重复,创建了General目录存放通用脚本(如Axis相机操作、SNMP陷阱发送等),目录结构如下:
home |- General/ |- venv/ |- axis_operations.py |- readfile.py |- remote_operations.py |- snmptrap.py |- homeclass.py |- AxisCamera/ |- venv/ |- axis_cameras_status.py |- Stats/ |- venv/ |- getstatsfromremoteserver.py
尝试在AxisCamera虚拟环境的axis_cameras_status.py中导入General目录的axis_operations.py,但axis_operations.py依赖的requests仅安装在General的虚拟环境中,执行时出现错误:
(venv) user@server:~/AxisCamera> python axis_cameras_status.py Traceback (most recent call last): File "axis_cameras_status.py", line 28, in <module> from axis_operations import AxisCamera File "/home/General/axis_operations.py", line 16, in <module> import requests #https://www.dataquest.io/blog/python-api-tutorial/ ModuleNotFoundError: No module named 'requests'
请问最佳的管理方案是什么?能否实现将通用脚本放在带独立虚拟环境的目录中,供其他所有虚拟环境调用?
方案1:将通用脚本打包为本地Python包(推荐)
把General目录改造为可安装的本地Python包,让每个项目的虚拟环境都能独立安装该包并自动获取其依赖,既保证通用代码的复用性,又维持各虚拟环境的独立性。
- 调整
General目录结构:
home/General/ |- setup.py # 打包配置文件 |- general/ # 核心包目录,将原通用脚本全部移入 |- __init__.py |- axis_operations.py |- readfile.py |- remote_operations.py |- snmptrap.py |- homeclass.py |- venv/ # 可选,仅用于通用包的开发调试
- 编写
setup.py示例:
from setuptools import setup, find_packages setup( name="general-utils", version="0.1", packages=find_packages(), install_requires=[ "requests>=2.0" # 明确声明通用包的依赖 ] )
- 在各项目虚拟环境中安装本地包:
激活AxisCamera的虚拟环境后,执行:
pip install /home/General
之后在axis_cameras_status.py中即可规范导入:
from general.axis_operations import AxisCamera
后续通用包更新时,重新执行安装命令即可同步到所有项目环境。
方案2:让项目虚拟环境继承通用环境依赖(不推荐,耦合性高)
如果暂时不想打包,可以通过添加路径的方式让调用方虚拟环境加载通用环境的依赖,但这种方式会破坏虚拟环境的独立性:
- 找到
General虚拟环境的site-packages路径,示例:
/home/General/venv/lib/python3.8/site-packages
(替换3.8为你的实际Python版本)
2. 在AxisCamera虚拟环境中创建.pth文件指向该路径:
激活AxisCamera虚拟环境后,执行:
echo "/home/General/venv/lib/python3.8/site-packages" >> $VIRTUAL_ENV/lib/python3.8/site-packages/general_deps.pth
- 在
axis_cameras_status.py开头添加General目录到Python搜索路径:
import sys sys.path.append("/home/General") from axis_operations import AxisCamera
该方案的问题是:通用环境的依赖变更会直接影响所有调用项目,极易引发版本冲突。
方案3:在所有项目虚拟环境中安装通用脚本依赖(简单但维护成本高)
直接在每个项目的虚拟环境中安装通用脚本需要的依赖,再添加General目录到Python路径:
- 激活
AxisCamera虚拟环境,安装依赖:
pip install requests
- 在
axis_cameras_status.py开头添加路径并导入:
import sys sys.path.append("/home/General") from axis_operations import AxisCamera
这种方式无需改造目录,但新增依赖时需要在所有项目环境中重复安装,长期维护成本高。
关于“通用脚本带独立虚拟环境供其他环境调用”的可行性
无法直接实现:Python解释器运行时只会加载当前激活虚拟环境的依赖,无法自动读取其他虚拟环境的包。方案1是最规范的解决方式,既保留了通用代码的独立性,又能让各项目环境按需获取依赖。
内容的提问来源于stack exchange,提问作者garvarma

