Python 的包管理感觉怎么这么不优雅。。。 - V2EX
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 21120 次点击
    这是一个创建于 2840 天前的主题,其中的信息可能已经有所发展或是发生改变。

    本人前端一枚,习惯了 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 的项目,经常指定库版本,不同的项目就需要不同的版本,而不是大家都有一个共识去适配最新版。这样导致了本地安装就必需要多版本共存,也做不到很好的复用,全局共享一个库就变得没有太大意义了。
    para
        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  
    PRO
       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  
    PRO
       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 Pyhon 社区有很多“约定俗成”,你得习惯它们,并且享受它们。譬如 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     Solana     3547 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 36ms UTC 05:03 PVG 13:03 LAX 22:03 JFK 01:03
    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