Python 依赖库的引用问题,感觉没有合适的方法

2023-07-03 14:02:00 +08:00
 huluhulu
总结来说,就是下面的引用关系:
项目 A 引用了开源代码 B 和 C 库,但是 B 用了 D 的 1.1 ,C 用了 D 的 2.0.
D 的 1.1 和 2.0 接口不兼容

怎么解决这个问题?感觉现有的 venv 解决方案都是为了不同开源库的隔离,而不是实现开源库之间的并存。

是不是目前最好的方法,只能自己修改 B 和 C ,让他们调用同一个版本的 D ?
1987 次点击
所在节点    Python
18 条回复
alexsz
2023-07-03 14:06:11 +08:00
修改 B 适配新版 D
tabris17
2023-07-03 14:41:21 +08:00
Dependency hell
如果版本冲突实在无法解决,只能拆成两个项目,或者在 B 和 C 舍弃其中一个
huluhulu
2023-07-03 14:49:36 +08:00
很多 tensorflow 的开源代码,依赖版本要求特别严格。如果真要适配,需要很多改动,没办法开箱即用了。
头疼。
llh880808
2023-07-03 14:54:07 +08:00
可以考虑使用 monkey patch

在模块 A 中重新实现 b 中的 call_foo 方法,就不会报错了

(记得空格会被吞,以下用.代替行首空格了)

```python
# file a.py
import b
import c

from d import foo

def call_foo():
....# 重新实现 call_foo 方法
....foo(3, 4, 5)

# 修改 b 的 call_foo 方法
b.call_foo = call_foo

b.call_foo()
c.call_foo()

# file b.py
from d import foo

def call_foo():
....# 模拟调用 1.x 版本 d.foo(),传两个参数
....foo(1, 2)

# file c.py
from d import foo

def call_foo():
....# 模拟调用 2.x 版本 d.foo(),传三个参数
....foo(1, 2, 3)

# file d.py

# 模拟实现 2.x 版本 d.foo(),必须传三个参数
def foo(a, b, c):
....pass
```
lisongeee
2023-07-03 16:06:20 +08:00
如果是 js + pnpm 就没有这个问题,js 的依赖管理机制 天然支持 单个库的 多版本共存
lrigi
2023-07-03 16:16:03 +08:00
你能不能把两个 D 保存到本地文件夹,然后重命名为 D1 ,D2 ,然后分别引用各自的 D 就行了?
chenzi0103
2023-07-03 16:17:54 +08:00
可以试一下 poetry
Syiize
2023-07-03 18:14:29 +08:00
简单的方法就是将旧版本 D 包更名后安装,然后修改 B 使其使用旧版本的 D
bestcondition
2023-07-03 18:21:01 +08:00
我想问下 op 主遇到的具体是哪两个库有依赖冲突呢?
ClericPy
2023-07-03 18:36:19 +08:00
一开始想的是

pip install a==1.0 -t ./a1

pip install a==2.0 -t /a2

sys.path.extend(['./a1', './a2'])

后来一想, 实际没用. 遇到过, 强行升级/降级 解决的, 解决不了的走 RPC 了, 坑爹
hsfzxjy
2023-07-03 18:38:09 +08:00
如果是 tensorflow 冲突,前面说的应该都不奏效。只要同一个进程里存在两个版本的 tensorflow 极大概率会出问题,因为 tf 有很多 native 的代码,怎么改名都没用

如果对于 B 和 C ,你只是把他们当黑箱来应用,即只是简单地直接喂数据给 B 和 C 得到结果,有一个办法是把他们服务化。首先你分别为他们创建他们自己的 venv ,然后分别用两个 venv 的 python 起两个进程,你的主进程使用 IPC 和他们通信即可。
inhzus
2023-07-03 18:47:35 +08:00
楼上 +1 ,额外多起一个服务,本地 IPC 通信好了
wxf666
2023-07-03 18:54:46 +08:00
@lisongeee #5 python 有个类似的,pdm ,也支持整台电脑每个包只保留一份,然后通过软链接引用啥的。

但不清楚能不能多版本共存。。
lisongeee
2023-07-03 19:45:56 +08:00
@wxf666

nodejs 的 node_modules 机制本来就是为了多版本共存而存在的,但是也因此被诟病占用过多空间

pnpm 主要解决 node_modules 空间占用过多的问题
GQp2iM8UxnVk9KB0
2023-07-03 19:59:17 +08:00
conda 不行吗?
huluhulu
2023-07-03 23:08:59 +08:00
@hsfzxjy 嗯,这个方法也不错。直接当两个独立的服务。
xiaoqiao24
2023-07-07 14:47:15 +08:00
docker A 安装低版本,然后使用 A 作为 baseimage ,再安装高版本,最后打出来的镜像两个版本都有。
虽然在安装的时候会提示不兼容,但是并不影响安装。最后代码也能跑起来。
huluhulu
2023-07-07 16:51:46 +08:00
@xiaoqiao24 这真的是我未曾想到的方法

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/953656

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX