V2EX vwxyzjn
 vwxyzjn 最近的时间轴更新
vwxyzjn

vwxyzjn

V2EX 第 45338 号会员,加入于 2013-09-13 01:30:06 +08:00
vwxyzjn 最近回复了
2018-01-04 18:31:57 +08:00
回复了 serge001 创建的主题 Python Python 的包管理感觉怎么这么不优雅。。。
@ipwx 因为我最经常用 python 啊,但是想到以后写的代码会有这样重现问题就很头疼…
2018-01-04 17:18:07 +08:00
回复了 serge001 创建的主题 Python Python 的包管理感觉怎么这么不优雅。。。
@scriptB0y,@ipwx 您们说的约定俗成,向下兼容都是好的实践,但我说的重现能力…… 另外 js 未必就不能做你们说的最好实践。

所谓重现能力是我今天写的代码明天还能跑,而不是因为一些莫名其妙的原因不能跑了。和您们讲个自己的例子吧,我第一次写的小 /中型项目 https://github.com/streettraffic/streettraffic 用到了 websockets==3.3 这个依赖。我 setup.py 是乱写的,连版本号都没写,所以我写完几个月重装时发现跑不了了,后来 debug 之后发现是 websockets 高等版本破坏了原有的 api。

哪怕我在 install_requires 里面写了 websockets==3.3,只要别人在安装我的项目之后再安装一个项目有用到 websockets 的更高版本,我的代码就会报错了。

是的,我可以维护这个项目去修 bug,但是每个人的精力是有限的,并且你主要工作的项目也会变,所以我并不愿意改这个 api。我并不认为这样是错误的,并且我认为我写的代码如果能跑,便不应该因为这种依赖问题到后期某一天报错。
2018-01-04 17:02:18 +08:00
回复了 serge001 创建的主题 Python Python 的包管理感觉怎么这么不优雅。。。
@jhdxr 感同身受… 经常是 pip install 后出现一些奇怪的红字,然而无休无止无意义的依赖 debug 开始了
2018-01-04 16:53:57 +08:00
回复了 serge001 创建的主题 Python Python 的包管理感觉怎么这么不优雅。。。
@scriptB0y 另外我感觉我们说的似乎不是一个东西。我感觉您说的那个 requirement_base.txt 似乎更像是对项目的高阶描述:说的是我们主要的依赖是这些包,而我说的是 python/pip 缺乏重现能力。

> 基本不会冲突(我没遇到过),因为大家一般都是规定最低版本。如果真有两个包最高版本冲突,那说明其中有一个包太久不更新或者本身就存在问题,具体解决吧。

您的意思是似乎是说,出现了依赖冲突我们再想办法解决,而我是说,如果 pip 和 npm 一样,我们连这样的冲突都不会碰到,所以在这个角度上,pip 的设计是有缺陷和落后的。

另外您很少遇到不代表别人很少遇到,我 debug 这种依赖相关的 bug 应该不算少,总是要 pip uninstall,install,然后通过一番努力终于代码能跑。然而我厌倦了这种 debug,既然有 npm 这种一键解决你依赖问题的安装方式,为什么每次要自己找麻烦去手动解决依赖 bug 呢?
2018-01-04 16:37:59 +08:00
回复了 serge001 创建的主题 Python Python 的包管理感觉怎么这么不优雅。。。
@xpresslink virtualenv 和 pipenv 都没有解决 dependencies collision。请看我刚刚写的例子。
2018-01-04 16:35:32 +08:00
回复了 serge001 创建的主题 Python Python 的包管理感觉怎么这么不优雅。。。
@scriptB0y

> 发生这种事情本来就是不科学的,不过我还没遇到过。好像 pipenv 在解决这个问题。

恰恰相反,这种情况每时每刻都在发生。只是因为您们没有意识到而已。您写个项目,总得用些包吧?而您的包是有个固定版本的。假设您 1 月份装 anaconda,我 3 月份装 anaconda,很有可能我们的 pandas 版本不同。

我举一个很简单粗暴的例子来和您展示 python/pip 的包管理能有多么的糟糕。假如说您写了一个包,里面有代码``print(df.iloc[2])``( df 是 pandas.DataFrame 对象);再假设你的 pandas 版本为 1.0 ;然后假设我写了个包,里面有代码``print(df.indexloc[2])``;假设我的 pandas 版本为 1.1,并且在该版本中重新命名 DataFrame.iloc 为 DataFrame.indexloc。

那么这时候,如果一个人做另外一个项目用了我们的 dependency,他基本上是陷入了绝境。python 不允许一个包有多个版本同时存在。也就是说,如果他后 pip install 你的包,pandas 版本就是 1.0,这时候程序报错:indexloc undefined,因为我的包用了 pandas 新 api indexloc。那如果他后安装我的包,那么 pandas 版本为 1.1,这时候程序也报错:iloc undefined,因为他用了已经过时的 api iloc。

也就是说,你陷入了必定 bug 的局面。现在 python 没有好的办法可以解决这种问题。唯一的方式是:把 pandas 1.0 拷贝然后改名称 pandas_dummy,修改其中相关的代码( absolute import 可能会出问题),然后在你的包里写 import pandas_dummy as pandas.

虽然我用的是一个 dummy example,但是你可以想象得到,在当今项目依赖成百上千的包并且这些包在不同变化的前提下,这种情况应该是时有发生的。所以大多数包 depreciate api 的时候才会告诉你他们再过几个版本会 depreciate,也许这样会给你一些缓冲的版本来解决这种依赖冲突。

但是简单来说,你的程序没有重现的绝对保障。换句话来说,你的程序能不能跑有些看运气。
2018-01-04 12:22:53 +08:00
回复了 serge001 创建的主题 Python Python 的包管理感觉怎么这么不优雅。。。
@scriptB0y

这样不好… 我都不知道小型的项目要怎么手写这个
requirements.txt 。难道挑几个自己 import 的包写吗…?那万一漏一个怎么办,万一你选的这几个包依赖的包版本有冲突怎么办?
2018-01-04 11:15:47 +08:00
span class="gray">回复了 serge001 创建的主题 Python Python 的包管理感觉怎么这么不优雅。。。
@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 跑。也许某天某些包升级了,我的代码就失效了,这实在是让人担忧和痛心的事。

希望大家理性看待。
关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3143 人在线   最高记录 6679       Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 12ms UTC 12:42 PVG 20:42 LAX 05:42 JFK 08:42
Do have faith in what you're doing.
ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86