@
scriptB0y 不同意您的回答
> 我假设你说的是管理依赖?一般写到 requirements.txt 里面,手动写更容易控制版本和依赖。
实在不知道您是如何得出这个结论的。依赖是 nested 的。也就是有依赖的依赖的依赖。你不用软件来记录这些 nested dependencies,最后的结果就是 inderterministic build.
Pip 最大的问题是其缺乏重现能力… npm 的 package.json 和 npm install 虽然繁琐并且一个小小的项目就会用到几百兆的硬盘,但是其有极好的重现能力。也就是说,给你一个 package.json 和项目源码,你是可以重新跑这个项目的。
而 pip 的重现能力就令人质疑了。如果您随便去 github 找个 jupyter notebook,只要它用了一些小众的 library 像 websocket, aiohttp 之类的,很有可能那个 notebook 会跑出错误,因为 ipynb 并不记录其依赖的包。
在写过一段时间 npm 的代码后,我又重新写回了 python 代码,又出现一些奇奇怪怪的错误,然后我去 google 查这个错误,发现是某个包的版本错误了,然后我用 pip 来更新这个包,最后解决了这个 bug。但是我不应该要操心这种 bug。pip 应该帮我记录*所有*的依赖。
然而 pip 做依赖有各种各样的问题,有兴趣的可以看看这篇文章
https://medium.com/@alonisser/things-i-wish-pip-learned-from-npm-f712fa26f5bc?source=linkShare-c6ac3e2e940f-1515034677其中提到很有意思的一个事情,也就是 python 不允许一个 library 存在两个版本。但假如说你有两个包,包 A 依赖包
[email protected],包 B 依赖包
[email protected]。你用 pip 装完 A 和 B,你会发现包 C 是版本 1.1 *或者* 1.2 (看你安装的顺序)。但是实际这种情况经常发生,发生的时候你只能祈祷包 C 没做什么大的改动,所以代码还可以跑,但这毕竟还是显示了 python/pip 重现能力有很大问题。
有些人提到了 python 有 pipenv。这个项目确实不错,但是实际用起来*好像*还是有各种问题。我用过一次,但是装了一些依赖后又出现一些奇怪的错误,似乎和 C-extension python 包有关系,总之用得不像 npm 那样畅快。
看到大多数人都说 pip 比 npm 好,我觉得可以理解(因为你不用为每一个项目繁琐地装几百兆依赖),但是我认为这种看法是不深刻的。
我是很喜欢 python 的,但是每每想到这个问题就觉得很难受。觉得自己写的代码无法保证在别人电脑上也可以 deterministically 跑。也许某天某些包升级了,我的代码就失效了,这实在是让人担忧和痛心的事。
希望大家理性看待。