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
dwzhao
V2EX  ›  Python

如何能够获取到进程的第三方模块包版本号?

  •  
  •   dwzhao · 2020-08-19 12:45:19 +08:00 · 1438 次点击
    这是一个创建于 1555 天前的主题,其中的信息可能已经有所发展或是发生改变。
    最近接了个工作
    内容是:希望能够通过发指令给各个应用服务发消息,让各个服务汇报自己使用的第三方库版本信息。
    目的:能够确认各个应用的版本号,方便实时查看和管理。
    背景:各个服务因为启动时间很早的缘故,虽然所在机器的 requirement.txt 已经更新,但是进程内的第三方库版本还是旧的,一些接口不支持。

    做法:
    被否决的方法:
    1 、查 requestment.txt 和启动时间,这个自由度太大了,不方便。
    2 、跟进 path 中的信息来查看版本号,实际上和 1 一样
    3 、使用系统命令 pip list,虚拟环境下的进程怎么处理?
    想到的方法:
    1 、因为是要查看进程内的第三方库,所以需要 import 这个第三方库,比如 import redis,输出对应的版本 redis.__version__,这样做会有什么问题么,求各位提提想法和建议~
    10 条回复    2020-08-22 23:32:17 +08:00
    chinvo
        2
    chinvo  
       2020-08-19 13:04:28 +08:00 via iPhone
    pip 也是个包,可以 import 进来用
    18870715400
        3
    18870715400  
       2020-08-19 17:24:11 +08:00
    import subprocess
    pip_path = "~/miniconda3/bin/pip"
    res = subprocess.run("{} list".format(pip_path), shell=True, stdout=subprocess.PIPE)
    infos = res.stdout

    然后对 info 分割取包的版本信息
    dwzhao
        4
    dwzhao  
    OP
       2020-08-20 15:41:52 +08:00
    @18870715400 这样只是调用系 pip 查看包的版本,并不代表进程内用的就是这个版本的包呀。除非让进程重启,这个显然是不可能的。
    dwzhao
        5
    dwzhao  
    OP
       2020-08-20 15:51:04 +08:00
    @chinvo 看 pip 的 doc 里说:Even though pip is available from your Python installation as an importable module, via import pip, it is not supported to use pip in this way. For more details, see Fixing conflicting dependencies.
    chinvo
        6
    chinvo  
       2020-08-20 15:53:18 +08:00
    @dwzhao #5 只是 pip 官方不提供支持. 而且他说的这个用法主要是运行时安装新包. 只是用下 列出包 之类的功能, 不会有太大问题的.
    dwzhao
        7
    dwzhao  
    OP
       2020-08-20 16:18:21 +08:00
    @chinvo,实际上这样难点倒不是如何找到包的版本,而是确认进程中引用到的包的版本,同时不能因为检查这个包而引入这个包,同时也不愿意去主动 reload_model
    dwzhao
        8
    dwzhao  
    OP
       2020-08-20 21:21:11 +08:00
    用 pkg_resources 来查
    >>>import pkg_resources >>> pkg_resources.get_distribution("construct").version '2.5.2'

    print([p.project_name,p.version for p in pkg_resources.working_set])
    18870715400
        9
    18870715400  
       2020-08-21 11:02:26 +08:00
    @dwzhao 你的进程使用了哪个 python 环境就用对应环境的 pip 啊, 什么叫做"不代表进程内用的就是这个版本的包",难道你的一个环境同一个包还有多个版本么?
    JohnDHH
        10
    JohnDHH  
       2020-08-22 23:32:17 +08:00
    或许可以同 gdb 挂载进程可以帮你去实现。

    例如这样的文章有简单介绍: https://mozillazg.com/2017/07/debug-running-python-process-with-gdb.html
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5327 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 03:38 · PVG 11:38 · LAX 19:38 · JFK 22:38
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.