V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
serge001
V2EX  ›  Python

Python 的包管理感觉怎么这么不优雅。。。

  •  
  •   serge001 · 2018-01-03 23:00:14 +08:00 · 19958 次点击
    这是一个创建于 2514 天前的主题,其中的信息可能已经有所发展或是发生改变。

    本人前端一枚,习惯了 node 的 npm 之后感觉配置和使用起来都很简单方便,最近学习了一点 python 后,感觉 python 的包管理怎么这么不优雅。首先,配置文件居然是用 txt 文件来写的,二进制文件我用编辑器是无法打开的,然后用 git 也不能很好的版本管理;其次,pip install 是把包全都装在了全局,打开用户目录,一大堆以点开头的文件夹,抓狂。。。

    第 1 条附言  ·  2018-01-04 10:13:48 +08:00
    更新:昨晚是我傻逼了,txt 文件是文本文件来的。因为之前 fork 了一个 python 项目,里面的包依赖管理文件是 requirements.txt ,我用编辑器 atom 打开不知道为什么提示说不能打开二进制文件,所以误以为 txt 文件是二进制文件,今天又试了一下发现可以了。。。所以 git 版本控制是没问题的,不过还是很不理解为啥用 txt 来写。非常感谢各位大大提出的各种解决方案,感谢感谢~
    120 条回复    2018-01-23 17:06:55 +08:00
    1  2  
    scriptB0y
        1
    scriptB0y  
       2018-01-03 23:55:42 +08:00   ❤️ 6
    Python 的打包确实是比较复杂,你可以看看这个 template: https://github.com/kennethreitz/setup.py

    但是你后面的结论就不对了:

    > 配置文件居然是用 txt 文件来写的

    不知道什么意思……文件要么二进制文件要么文本文件,txt 是什么?

    > 二进制文件我用编辑器是无法打开的

    这是你编辑器的问题。况且你为什么要用编辑器打开二进制文件?你期望看到什么?

    > 然后用 git 也不能很好的版本管理

    我假设你说的是管理依赖?一般写到 requirements.txt 里面,手动写更容易控制版本和依赖。

    > pip install 是把包全都装在了全局

    用 virtualenv,python 的环境可以非常干净的

    > 打开用户目录,一大堆以点开头的文件夹

    你说的点开头的文件是什么?就算装到系统里面,也是在 site-package 里面。

    ------

    最后多说一句,少抱怨,多去 Stack Overflow 找找解决方案。我向你保证 Python 的依赖可以处理地很干净的。比起 JavaScript 来坑少很多了。

    贴点资料: https://www.kawabangga.com/how-to-learn-python
    brucezz
        2
    brucezz  
       2018-01-04 00:14:45 +08:00
    Kilerd
        3
    Kilerd  
       2018-01-04 00:51:44 +08:00   ❤️ 3
    你怕不是没遇到过这种情况咯。

    JavaScript 莫名奇妙不工作,然后把 nodule_modules 文件夹删了,然后再 yarn 一下就可以了。 依赖库完全没改变。 神奇吧。
    feather12315
        4
    feather12315  
       2018-01-04 00:55:41 +08:00 via Android   ❤️ 1
    为啥要 pip 安装?能不 pip 就不 pip 啊,安装源里的多好
    quinoa42
        5
    quinoa42  
       2018-01-04 01:18:50 +08:00
    什么二进制文件需要用编辑器编辑还得用 git 管理……
    nicevar
        6
    nicevar  
       2018-01-04 01:35:22 +08:00   ❤️ 1
    node 和 python 半斤八两,开源的项目都是一堆 issue 都是跑不起来的,全死在版本上
    congeec
        7
    congeec  
       2018-01-04 01:48:49 +08:00 via iPhone   ❤️ 2
    Do one thing, do it well. 这是 unix 的哲学,是传统,pipenv, pyenv 啥的还算好用

    npm 那种啥都能干的工具才是异端

    很多 linux 新手跟我抱怨 Linux 真难用,那是因为他们爸 Linux 当 windows 用。你那 pip 当 npm 用,自然要吃瘪
    ysc3839
        8
    ysc3839  
       2018-01-04 01:48:59 +08:00 via Android
    一堆点开头说明你用的是 Windows 吧,手动隐藏就好了啊。
    hsuan
        9
    hsuan  
       2018-01-04 01:49:41 +08:00 via Android
    @feather12315 不用 pip 用啥?
    PythonAnswer
        10
    PythonAnswer  
       2018-01-04 01:50:52 +08:00 via Android
    现在自带 venv 了 还算高级。

    多看说明书,都有最佳操作的。
    param
        11
    param  
       2018-01-04 02:10:13 +08:00   ❤️ 2
    Python 的包管理很科学,npm 的包管理才是非常不科学。
    即便这样,我在 ArchLinux 上还是用 pacman 来装 Python 包,这样就能随着系统更新而滚动更新。官方源+archlinuxcn 源+AUR 覆盖了我大部分需要的包,剩下的用 pip install --user 来安装。
    至于 virtual env 的话,也只适合在开发环境用,针对特定项目使用,日常使用并不需要那么搞得复杂。如果你在对付一个老项目并且有大量的坑填不过来,那么就用它来维持一些旧版本的库吧,否则的话还是建议把所有的库更新到最新。
    param
        12
    param  
       2018-01-04 02:14:26 +08:00
    npm 的项目,经常指定库版本,不同的项目就需要不同的版本,而不是大家都有一个共识去适配最新版。这样导致了本地安装就必需要多版本共存,也做不到很好的复用,全局共享一个库就变得没有太大意义了。
    param
        13
    param  
       2018-01-04 02:24:19 +08:00
    我使用 Archlinux,其中一个原因也是他们把所有包都更新到最新,避免了我以前使用 debian/fedora 的那种 Dependency hell,摆脱了大量为了照顾老项目而影响体验的历史遗留问题。
    与此同时,npm 的依赖版本写死不更新却成为一种共识,有点可悲。
    PythonAnswer
        14
    PythonAnswer  
       2018-01-04 06:45:33 +08:00 via Android   ❤️ 1
    conda 一次安装 基本都够用了。
    huangunic0rn
        15
    huangunic0rn  
       2018-01-04 07:46:33 +08:00 via Android   ❤️ 3
    蛤蛤 npm 居然嘲笑 pip 🙈
    jingniao
        16
    jingniao  
       2018-01-04 08:03:24 +08:00 via Android
    pip 已经挺好了……
    当然在一些依赖传递时可能会有一些冲突,不过没碰到过
    你让 go 怎么活?官方软件包管理工具的难产……
    zachguo
        17
    zachguo  
       2018-01-04 08:18:47 +08:00   ❤️ 2
    python 的包管理就不要洗了,公认的很糟糕了。要是涉及到 numpy 之类 cbinding,打包那可是各种 hack。
    不管 npm 还是 yarn 都比 pip 强,deploy 的话有个 Dockerfile 和 npm i 就不会出问题; python 就看运气了,即便 docker、conda/venv 用上了还会有幺蛾子。
    之前 deploy 一个 ML 的 service,必须把 numpy 从 requirements.txt 里拉出来单独跑一遍 pip install 才行,逗我。
    Acebiu
        18
    Acebiu  
       2018-01-04 08:21:05 +08:00 via Android
    至少比 npm 问题少多了,npm 是真的迷。(怨气满满的说道。
    blless
        19
    blless  
       2018-01-04 08:37:27 +08:00 via Android
    @zachguo numpy 是有点奇葩,而且其实你真的要用其实还要装一些 openblas 还有其他 intel cuda 加速模块。我们都是用 docker 直接做一个通用基础镜像。
    klgd
        20
    klgd  
       2018-01-04 08:45:44 +08:00
    @Kilerd #3 多么痛的领悟啊,我就经常这么干
    jsfaint
        21
    jsfaint  
       2018-01-04 08:54:44 +08:00
    你需要 pipenv
    wucancc
        22
    wucancc  
       2018-01-04 08:54:50 +08:00
    @Kilerd 经常遇到,也是这么解决的。
    toono
        23
    toono  
       2018-01-04 08:56:11 +08:00
    pipenv 算是比较新的比较先进的。每个项目会有依赖列表文件,依赖安装的位置也是确定的
    TangMonk
        24
    TangMonk  
       2018-01-04 08:58:27 +08:00 via Android
    bundler 路过
    secsilm
        25
    secsilm  
       2018-01-04 09:01:26 +08:00 via Android   ❤️ 1
    听你们说 pip 很坑的样子,可能是我用了个假的 pip 吧
    qsnow6
        26
    qsnow6  
       2018-01-04 09:04:48 +08:00
    pip 是不考虑安装环境的,如果你要安装的库里面需要系统环境支持的话,就需要自己把环境配好。
    比如 lxmlx,就是个大魔王,网上搜下,多少人躺过这个坑。

    如果不涉及 C 库或者系统环境还好,不然还真的蛮头疼的。

    所以 conda 就是为了解决这个的,真的很好用,安装包的时候,顺带帮你把这个包所需的环境包也装了。
    rocksolid
        27
    rocksolid  
       2018-01-04 09:05:07 +08:00
    windows 下面 pip 的确蛮烦的
    Mark24
        28
    Mark24  
       2018-01-04 09:05:48 +08:00
    @Kilerd 遇到过,热更新总是延时,也是这样解决的。
    onlyice
        29
    onlyice  
       2018-01-04 09:09:37 +08:00
    对于 Python 库,可以用 pipenv,最新的最佳实践。

    如果是带 C 扩展的 Python 库(比如 mysqlclient ),会麻烦一点,需要保证你的系统环境上有相应的 C 库(如 libmysqlclient.so )。这块可以看下 Anaconda 的实现。
    doubleflower
        30
    doubleflower  
       2018-01-04 09:10:46 +08:00 via Android   ❤️ 3
    pip 的确比 npm 设计上差老多了。
    但是因为 python 不像 js 包分的很细很多,py 项目总的包数量是很少的,所以还能处理。如果 py 也像 js 几行代码都能做一个包,那他这个设计早就崩溃了。
    LokiSharp
        31
    LokiSharp  
       2018-01-04 09:14:21 +08:00
    所以,有了 pipenv 啊
    psuwgipgf
        32
    psuwgipgf  
       2018-01-04 09:17:17 +08:00
    我用 python 写爬虫的时候也是这样想的,不过后来用了 golang。。。。
    lihongjie0209
        33
    lihongjie0209  
       2018-01-04 09:23:59 +08:00
    pip 和 npm 都挺难用的
    bolide2005
        34
    bolide2005  
       2018-01-04 09:28:19 +08:00
    python 的包管理在各类第三方工具的帮助下已经算是比较“优雅”的了
    不然你试试 golang ……
    feather12315
        35
    feather12315  
       2018-01-04 09:37:53 +08:00 via Android
    @hsuan Linux ? 装软件软件源里的,几乎都有。没有的自己打包个。
    circleee
        36
    circleee  
       2018-01-04 09:44:00 +08:00
    @Kilerd 遇到过。
    circleee
        37
    circleee  
       2018-01-04 09:44:27 +08:00
    @huangunic0rn .............
    Tink
        38
    Tink  
       2018-01-04 09:48:58 +08:00
    virtualenv
    anasplrt34
        39
    anasplrt34  
       2018-01-04 09:49:15 +08:00
    用了 golang 的包管理 你就会觉得 pip 是多么优秀了 www
    guyskk0x0
        40
    guyskk0x0  
       2018-01-04 09:52:42 +08:00 via Android
    @zachguo 带 C 拓展的确实很复杂,尤其是 Linux,不同系统依赖的动态链接库不一致,在脚步语言里是硬伤,npm 也有类似的问题,只不过它很少带 C 拓展的库。docker 按理说不会有这种问题。
    wibile
        41
    wibile  
       2018-01-04 09:53:34 +08:00
    npm 五十步笑百步啊。。。。。pip 确实不优雅,npm 简直了。。。。。
    airborne007
        42
    airborne007  
       2018-01-04 09:57:07 +08:00
    npm 居然敢说 pip ?
    janxin
        43
    janxin  
       2018-01-04 09:58:52 +08:00
    npm 能嘲笑的大概只有 go 和 C++了吧?
    j717273419
        44
    j717273419  
       2018-01-04 10:00:38 +08:00
    python10 年前的代码,今天还能用。
    nodejs10 个月前的代码,今天怎么用?
    serge001
        45
    serge001  
    OP
       2018-01-04 10:20:40 +08:00
    @scriptB0y 感谢感谢,早上起来一看感觉自己无脑发的帖子好傻逼😭😭
    g0thic
        46
    g0thic  
       2018-01-04 10:21:49 +08:00
    学的姿势不对啊

    一般教程不都是教你先安装一个虚拟环境的么 这样可以避免包的混乱和版本冲突
    XIVN1987
        47
    XIVN1987  
       2018-01-04 10:27:44 +08:00 via Android   ❤️ 1
    所以楼主可以在发个帖子控诉下辣椒编辑器 atom 把 txt 文件识别成二进制文件⊙∀⊙?
    Tyanboot
        48
    Tyanboot  
       2018-01-04 10:31:17 +08:00 via Android
    优雅?知乎看多了?
    whx20202
        49
    whx20202  
       2018-01-04 10:31:31 +08:00
    没有任何嘲讽的意思哈,但是网上评价好像 npm 比 pip 要挫一点把
    前一阵子不是还有个 nodejs 开发者 删了自己的库,那个库是字符串处理的,
    导致几十个 几百个知名的库都不能用的问题吗
    jyf
        50
    jyf  
       2018-01-04 10:34:07 +08:00
    楼上的嘲讽都没什么意思

    我理解楼主说的 txt 应该是指相对于 npm 用 json 这种有格式的配置 为何 pip 要用 txt 这种没格式的

    首先 pip 的 txt 其实也是有微格式的 只是你可能没用到 只是看到名字罗列而已
    其次 基于行文本是个 unix 传统 可能 pip 的作者比较欣赏这种 又或者只是遵循了周围的惯例
    最后 安装到全局这个确实不如 npm 方便 但是 npm 出来前 大家都是默认这么干 也没什么好说的 可以去推动他改 至于说用户目录下一堆点开头的目录 这又是一个 unix 传统 :D

    PS 感觉现在社区总是嘲讽多 回答少 不如从前了
    param
        51
    param  
       2018-01-04 10:34:57 +08:00
    @zachguo 那么 npm 的 cbinding 怎么处理?
    Cambrian07
        52
    Cambrian07  
       2018-01-04 10:36:50 +08:00
    我觉得 txt 没毛病啊
    Wolther47
        53
    Wolther47  
       2018-01-04 10:42:36 +08:00 via iPhone
    @jingniao #16 golang 的包管理真的差
    yichinzhu
        54
    yichinzhu  
       2018-01-04 10:47:49 +08:00 via Android
    npm 的 package.json 本质不还是 txt,有什么区别,,,
    KgM4gLtF0shViDH3
        55
    KgM4gLtF0shViDH3  
       2018-01-04 10:55:53 +08:00
    npm 才恶心。。动不动一堆错误警告,想尝试一下都报打击的没欲望了。
    param
        56
    param  
       2018-01-04 10:58:48 +08:00
    其实大多数包,在 archlinux 下用 pacman 或者 AUR 装,都自动处理好了 C 库的依赖。
    装 python-lxml 的时候,会自动安装依赖 libxslt,装 python-scipy 会自动安装 scipy。
    param
        57
    param  
       2018-01-04 11:08:39 +08:00
    关于包的列表,以行来分割有很大的方便性。sed、grep、xarg、cut 等等的工具都是以行为单位处理的。
    我就是通过 pip freeze > pip_package_list 来备份包列表,同时把列表放在 dotfiles 里面的。
    我最近尝试在我的 dotfiles 下加一个 Dockerfile,通过 docker 来让我的服务器保持跟我桌面一样的环境(装相同的软件,相同的 zsh、vim 配置)。
    我在 Dockerfile 里的其中一个操作就是 pip install -r <(cut -d = -f 1 pip_package_list) --user,通过 cut 命令来把版本号截掉,从而让 pip 安装最新版本。
    wizardoz
        58
    wizardoz  
       2018-01-04 11:10:15 +08:00
    npm install 一次都能下班了,我说什么了吗?
    vwxyzjn
        59
    vwxyzjn  
       2018-01-04 11:15:47 +08:00 via iPhone   ❤️ 4
    @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 跑。也许某天某些包升级了,我的代码就失效了,这实在是让人担忧和痛心的事。

    希望大家理性看待。
    arvinwangzj
        60
    arvinwangzj  
       2018-01-04 11:37:36 +08:00
    个人觉得 pip 还是很好用的,关于安装在全局的问题,不同项目可以使用 virtualenv,就可以独立安装,互不影响。virtualenv 操作又不繁琐
    tonghuashuai
        61
    tonghuashuai  
       2018-01-04 11:38:12 +08:00   ❤️ 7
    XIVN1987
        62
    XIVN1987  
       2018-01-04 11:48:03 +08:00
    @tonghuashuai
    好黑!!
    zachguo
        63
    zachguo  
       2018-01-04 11:56:59 +08:00 via Android
    @param 经常会看到 node-gyp,不管是安装或者定义依赖用户都不需要做额外的事情。
    zachguo
        64
    zachguo  
       2018-01-04 12:00:09 +08:00 via Android
    @arvinwangzj 有些包还是会在全局写文件。。即便用了 venv。
    zj299792458
        65
    zj299792458  
       2018-01-04 12:07:30 +08:00 via iPhone
    你颠覆了我对二进制文件的理解……
    scriptB0y
        66
    scriptB0y  
       2018-01-04 12:07:48 +08:00
    @vwxyzjn

    > 实在不知道您是如何得出这个结论的。依赖是 nested 的。也就是有依赖的依赖的依赖。你不用软件来记录这些 nested dependencies,最后的结果就是 inderterministic build.

    你说的软件记录指的是 `pip freeze > requirements.txt` 吗? 这样的确可以将所有包的版本准确导出。但是并不是推荐的做法。加入你只依赖了 requests,自动导出会将 requests 依赖的库(当前 pip 所有的依赖)都导出。你自己看到这个文件,都不知道哪些是项目依赖的,哪些是 requests 依赖的了。

    我的观点是,Python 的 requirements.txt 应该是可读的。如果你的项目依赖了除标准库的 requests,那么就在文件里面写 requrests (指定最小版本或者不指定),requests 的依赖交给 requests 去搞定。这样不好吗?
    ivechan
        67
    ivechan  
       2018-01-04 12:12:56 +08:00
    pip npm go 都不行( C++有包管理?)
    求推荐一个包管理做的好的语言入坑?
    scriptB0y
        68
    scriptB0y  
       2018-01-04 12:13:30 +08:00   ❤️ 1
    @vwxyzjn

    > 其中提到很有意思的一个事情,也就是 python 不允许一个 library 存在两个版本。但假如说你有两个包,包 A 依赖包 [email protected],包 B 依赖包 [email protected]。你用 pip 装完 A 和 B,你会发现包 C 是版本 1.1 *或者* 1.2 (看你安装的顺序)。

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

    我还是坚持我的观点,如果用 requirements.txt 写依赖的话,应该是人工维护,可读,不写依赖的依赖。比如这个:

    https://github.com/getsentry/sentry/blob/master/requirements-base.txt
    vwxyzjn
        69
    vwxyzjn  
       2018-01-04 12:22:53 +08:00 via iPhone
    @scriptB0y

    这样不好… 我都不知道小型的项目要怎么手写这个
    requirements.txt 。难道挑几个自己 import 的包写吗…?那万一漏一个怎么办,万一你选的这几个包依赖的包版本有冲突怎么办?
    airborne007
        70
    airborne007  
       2018-01-04 12:23:24 +08:00
    @tonghuashuai 漂亮
    Sparetire
        71
    Sparetire  
       2018-01-04 12:28:54 +08:00 via Android
    感觉 npm 比 pip 来得好用,虽然下载的依赖大一点,多一点,不过部署起来挺方便,说 node_modules 目录嵌套深的,那已经是以前的事了,npm install 换淘宝源也不慢,现在 npm 的安装速度和 yarn 也差不多了
    crysislinux
        72
    crysislinux  
       2018-01-04 12:29:06 +08:00 via Android
    npm 把 pip 吊起来打,实际使用问题多无非是因为 js 包很多,更新快,而且还支持多个版本共存。pip 要是处理这种情况,早完犊子了
    xpresslink
        73
    xpresslink  
       2018-01-04 13:15:20 +08:00
    @vwxyzjn 不会玩 Virtualenv 么? 直接把整个环境打包移到目标环境就行了. 最笨的办法 pip download 包在本地目录.
    tairan2006
        74
    tairan2006  
       2018-01-04 13:29:07 +08:00
    pipenv 还好吧,另外 npm 嵌套路径过深的问题应该解决了吧已经…
    scriptB0y
        75
    scriptB0y  
       2018-01-04 13:29:40 +08:00
    @vwxyzjn 用到了什么外部依赖就写什么呀,自己依赖的什么必须要清楚啊,总不能稀里糊涂把当前的环境的依赖都生成进去吧。既然是小型项目,那还要有多少外部依赖?

    怎么可能漏?

    基本不会冲突(我没遇到过),因为大家一般都是规定最低版本。如果真有两个包最高版本冲突,那说明其中有一个包太久不更新或者本身就存在问题,具体解决吧。
    jhdxr
        76
    jhdxr  
       2018-01-04 14:00:43 +08:00
    @j717273419 10 年前的 Python 现在还能用你怕是在做梦,Python 是两种语言的梗是怎么来的都忘了?

    另外上面居然又这么多人支持 pip 觉得没问题我真的是很好奇都是只写过 Python 没写过其他语言吗?
    已经有人指出了一个场景,就是不同依赖依赖了某一个包的不同版本。 @scriptB0y 我同意你的看法版本冲突的时候是存在问题,并且这种问题一般无法自动解决。但这种情况不应该报错终止吗?而不是默默的根据安装顺序去决定

    依赖文件放在全局而非项目里这个上面已经有人提供解决方案了。

    另外就是各种系统 /环境依赖相关的依赖,比如各种需要自己去编译 C 源码的依赖都是坑。

    反正 Python 的项目我见到能够拿到手直接 pip install -r 然后就能成功安装依赖并跑起来的项目真的是太少太少了_(:з」∠)_
    957204459
        77
    957204459  
       2018-01-04 15:53:34 +08:00
    没感觉到难用啊
    vwxyzjn
        78
    vwxyzjn  
       2018-01-04 16:35:32 +08:00 via iPhone   ❤️ 2
    @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,也许这样会给你一些缓冲的版本来解决这种依赖冲突。

    但是简单来说,你的程序没有重现的绝对保障。换句话来说,你的程序能不能跑有些看运气。
    vwxyzjn
        79
    vwxyzjn  
       2018-01-04 16:37:59 +08:00 via iPhone
    @xpresslink virtualenv 和 pipenv 都没有解决 dependencies collision。请看我刚刚写的例子。
    ipwx
        80
    ipwx  
       2018-01-04 16:49:17 +08:00
    @vwxyzjn 你太依赖“每个依赖包版本必须精确到 minor version ”这个事实了。Python 社区的 major version 兼容性和 depreciate api 是好事,JS 那种根本不敢升级依赖包版本的才是耍流氓。开源软件包修个小 bug 是常见的事情,Python 升级依赖包版本我基本都是无脑做的,npm 你升级依赖包版本哪次不是胆战心惊。
    scriptB0y
        81
    scriptB0y  
       2018-01-04 16:51:11 +08:00
    @vwxyzjn 我知道你说的这种情况,但是真的我自己没遇到过…… 一般的包都会努力去兼容最新的依赖。

    像你说的这个例子,我觉得根源不在包管理器上,而在设计的软件向后兼容上。这个问题不像是包管理器能解决的吧。就像 a.py 用的 python2 ; b.py 用的 python3,想要在一个程序 import a, b 怎么可能呢?
    ipwx
        82
    ipwx  
       2018-01-04 16:52:25 +08:00
    @vwxyzjn Python 社区有很多“约定俗成”,你得习惯它们,并且享受它们。譬如 x.y.z,社区标准是保证 x. 不变程序就能跑,y 不变不会加入新功能。大家写程序也会考虑这个原则,如果不能,那么这个包大概是无法成为知名的包。

    当然,特殊规定是,0.y.z 不考虑兼容性。直到 1.0.0 以后才有这个规定。所以你举得例子 pandas,不巧它才 0.20 。NumPy 已经 1.0 了,TensorFlow 也是,所以可以期待其兼容性。
    vwxyzjn
        83
    vwxyzjn  
       2018-01-04 16:53:57 +08:00 via iPhone
    @scriptB0y 另外我感觉我们说的似乎不是一个东西。我感觉您说的那个 requirement_base.txt 似乎更像是对项目的高阶描述:说的是我们主要的依赖是这些包,而我说的是 python/pip 缺乏重现能力。

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

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

    另外您很少遇到不代表别人很少遇到,我 debug 这种依赖相关的 bug 应该不算少,总是要 pip uninstall,install,然后通过一番努力终于代码能跑。然而我厌倦了这种 debug,既然有 npm 这种一键解决你依赖问题的安装方式,为什么每次要自己找麻烦去手动解决依赖 bug 呢?
    vwxyzjn
        84
    vwxyzjn  
       2018-01-04 17:02:18 +08:00 via iPhone
    @jhdxr 感同身受… 经常是 pip install 后出现一些奇怪的红字,然而无休无止无意义的依赖 debug 开始了
    renothing
        85
    renothing  
       2018-01-04 17:02:22 +08:00
    无论是 pip 还是 pipenv 都没解决依赖冲突,一个项目两个包依赖同一个包不同版本的情况。
    vwxyzjn
        86
    vwxyzjn  
       2018-01-04 17:18:07 +08:00 via iPhone   ❤️ 1
    @scriptB0y,@ipwx 您们说的约定俗成,向下兼容都是好的实践,但我说的重现能力…… 另外 js 未必就不能做你们说的最好实践。

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

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

    是的,我可以维护这个项目去修 bug,但是每个人的精力是有限的,并且你主要工作的项目也会变,所以我并不愿意改这个 api。我并不认为这样是错误的,并且我认为我写的代码如果能跑,便不应该因为这种依赖问题到后期某一天报错。
    wibile
        87
    wibile  
       2018-01-04 17:53:29 +08:00
    @vwxyzjn 大哥,这问题明显需要升级来解决啊。包 1 和包 2 都是活跃的项目,基本不会有类似问题,人家肯定会做依赖升级啊。如果不是活跃的项目,手动 fork 一下,自己适配。所以啊,别用些没人用的包。。。给自己找麻烦。。。
    mooncakejs
        88
    mooncakejs  
       2018-01-04 18:00:58 +08:00
    又吵起来了哈哈,再怎么否认,python 的包管理对于项目开发就是一坨屎(作为系统工具还是可以的),各种 env 就是尝试把这坨屎的臭味盖起来。
    kslr
        89
    kslr  
       2018-01-04 18:05:06 +08:00
    感觉 PIP 真的是比 NPM 麻烦多了,比如环境的多版本,搞一堆方案,哪有带着依赖走爽。我现在也只用可以打包依赖的语言。
    ipwx
        90
    ipwx  
       2018-01-04 18:13:26 +08:00
    @vwxyzjn All right,你说的问题确实存在,但是 virtual env / anaconda env / docker 不是都能解决你的问题嘛?我觉得总有一款合适,所以不是什么大问题。

    @mooncakejs 您这话说的。为什么不把 pip + virtual env / anaconda env 当做一个整体看,那样不就清静了么?还有 @kslr 您说的这个需求,Anaconda 就支持。如果你更勤快点,Docker 也不错。总而言之您二位为什么就偏要把 pip 单独拿出来批判一番呢?
    mooncakejs
        91
    mooncakejs  
       2018-01-04 18:21:38 +08:00
    @ipwx anyway,任何缺陷都是可以修正的,比如这几天的 CPU bug,只不过弥补缺陷的代价不一样。 docker 对于这些依赖问题确实可以解决,但也只是比较好看的“布”罢了。
    kslr
        92
    kslr  
       2018-01-04 18:22:41 +08:00
    @ipwx #90 如果你能接受,没有人阻止你。再者我只表达意见,没有说服其他人的兴趣。
    jhdxr
        93
    jhdxr  
       2018-01-04 18:29:53 +08:00   ❤️ 1
    @ipwx 那些不是包管理工具,那些已经是用来给 pip 这么一个巨坑在那填坑的工具了
    vwxyzjn
        94
    vwxyzjn  
       2018-01-04 18:31:57 +08:00 via iPhone
    @ipwx 因为我最经常用 python 啊,但是想到以后写的代码会有这样重现问题就很头疼…
    blless
        95
    blless  
       2018-01-04 19:11:30 +08:00 via Android
    说白了就是 npm 支持多版本管理呗 。很难想象一个项目用那么包还要凑一起…要我们早就拆成不同服务了。我还是倾向单一版本管理… npm 用得我真的难受
    swulling
        96
    swulling  
       2018-01-04 19:16:27 +08:00
    现在 Pip 的问题是依赖,很多人直接 pip freeze > requirements.txt 简直想屎,没有依赖链很难受
    crysislinux
        97
    crysislinux  
       2018-01-04 19:17:21 +08:00
    说 npm 难受的,你们像用 pip 一样用 npm,就没问题了。。
    leemove
        98
    leemove  
       2018-01-04 19:28:37 +08:00
    v2 里面敢黑 python?宝宝你是不想活了.
    ????????????赶紧叫 js,php 来主动接锅.
    leemove
        99
    leemove  
       2018-01-04 19:29:28 +08:00
    @crysislinux Npm 难用不在 npm 本身,在于 npm 不是 python 的生态.所以都不许好用!
    winglight2016
        100
    winglight2016  
       2018-01-04 19:30:37 +08:00
    之前不是有个帖子在说:python 性能差是公认的吗?不要用 python 做复杂业务就可以了吧,我猜。。。

    另外,conda 新建 environment 也很简单啊,多版本管理没什么问题的
    1  2  
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5709 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 06:13 · PVG 14:13 · LAX 22:13 · JFK 01:13
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.