V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
ggp1ot2
V2EX  ›  程序员

Python 有没有优雅的修改使用第三方库的办法?

  •  
  •   ggp1ot2 · 2022-09-27 20:42:10 +08:00 · 3099 次点击
    这是一个创建于 806 天前的主题,其中的信息可能已经有所发展或是发生改变。

    大概是这样。

    比如我现在项目 A ,用到了 B ,C 两个库。

    但是这两个库的部分功能我不满意,因此我去 site-packages 文件夹下找到这俩库的目录,并修改了这辆库的部分文件。

    但是这样的话,每次我要想在另外一台机器上部署这个项目,我需要先创建虚拟环境,然后复制拉取项目 A 的全部内容,然后进入到该虚拟环境下,找到库 B 、C 的目录,替换掉我修改的文件,才能成功运行。

    这样有点太麻烦了,每次修改,不仅要打包项目文件,还要把 B 、C 库给找到且打包了。

    有没有一种办法,可以更优雅一点?

    例如,是否可以在项目 A 下,把 B 、C 库直接加进去,然后直接在这里面的 B 、C 所在的文件夹下修改,这样我只需要保存项目 A 一个文件夹就可以了。

    另外一个需要说明的是,我不是直接使用了 B 、C 两个库,即不是直接 import B xxxx ,这两个库是另外几个库所依赖的。。。

    总感觉我这样,每次特别蠢。。。

    23 条回复    2022-09-28 17:43:56 +08:00
    ysc3839
        1
    ysc3839  
       2022-09-27 20:49:51 +08:00 via Android
    改代码,生成 wheel 文件,然后在虚拟环境下安装 wheel
    zmxnv123
        2
    zmxnv123  
       2022-09-27 20:51:06 +08:00
    试试猴子补丁的思想?
    hsfzxjy
        3
    hsfzxjy  
       2022-09-27 20:59:52 +08:00 via Android
    建议猴子补丁
    westoy
        4
    westoy  
       2022-09-27 21:09:11 +08:00   ❤️ 1
    fork 自己维护

    monkey patch 万一碰到不守武德在小版本做特性破坏式更新的, 那就故事变事故了
    ggp1ot2
        5
    ggp1ot2  
    OP
       2022-09-27 21:17:36 +08:00
    @westoy #4 理论上我永远停在这个版本,不更新应该没有问题吧
    Jirajine
        6
    Jirajine  
       2022-09-27 21:30:27 +08:00   ❤️ 1
    把那两个库 vendor 到自己的项目里
    lambdaq
        7
    lambdaq  
       2022-09-27 22:20:50 +08:00
    小修小改的话直接 hack 啊,比如 sentry 的库限制了 500 字符,我就直接 import 那个然后给改掉

    我经常这样干。不如你把库帖出来
    Cooky
        8
    Cooky  
       2022-09-27 22:26:01 +08:00
    自己建个库 E 把 B C 包装一下
    crysislinux
        9
    crysislinux  
       2022-09-27 23:27:40 +08:00 via Android
    这时候知道 npm 的好了吧。。monkey patch 不要太容易。
    crab
        10
    crab  
       2022-09-27 23:35:07 +08:00
    fork 一份,指定安装。
    ClericPy
        11
    ClericPy  
       2022-09-28 00:02:11 +08:00
    都提了猴子补丁, 这也是用了有 bug 第三方库时候垂死抢救的最简单途径...

    前面提到破坏式更新会导致猴子补丁失效, 可以考虑通过开闭原则实现个适配器之类的方式, 如果必须要侵入式魔改, 那就冻结版本吧...
    c0xt30a
        12
    c0xt30a  
       2022-09-28 01:14:22 +08:00
    自己 fork 一份,然后用 pip 之类的指定位置安装。只要能保证先安装了 B 跟 C ,然后再安装你 fork 的那份就可以了。pip 这个包管理器似乎对覆盖已经存在的文件或者软件包并不在意。
    c0xt30a
        13
    c0xt30a  
       2022-09-28 01:15:53 +08:00
    另外的办法是做个 patch ,每次自动构建的时候在 pipline 里自动 patch B 跟 C 。

    意见仅供参考。
    ruanimal
        14
    ruanimal  
       2022-09-28 09:49:46 +08:00
    简单点的方法就是把修改过的版本复制到项目的根目录
    ggp1ot2
        15
    ggp1ot2  
    OP
       2022-09-28 09:54:48 +08:00
    @ruanimal #14 但是每次修改一点,就要弄好几个文件夹,感觉特别麻烦
    ruanimal
        16
    ruanimal  
       2022-09-28 09:57:24 +08:00
    @ggp1ot2 那么你应该思考一下了,是不是用法不对,基本没有需要频繁修改三方库的场景。

    或者举个具体的例子看看
    fkdtz
        17
    fkdtz  
       2022-09-28 10:00:12 +08:00
    1. 自己继承并重写部分方法
    2. fork 自己的仓库版本
    3. 元编程
    killva4624
        18
    killva4624  
       2022-09-28 10:06:27 +08:00
    import 相关对象修改,然后当成一个公共库使用。
    1018ji
        19
    1018ji  
       2022-09-28 10:20:30 +08:00
    @lambdaq sentry 咋改 求教
    SoulMelody
        20
    SoulMelody  
       2022-09-28 10:22:14 +08:00
    subjadeites
        21
    subjadeites  
       2022-09-28 11:37:01 +08:00 via Android
    小范围就继承重写
    大改就自己 fork ,然后部署 /更新脚本里加两行拉取到指定位置就行
    还有一些文件数量比较小的可以直接复制到 utils 这种目录下做项目内置公共方法
    lambdaq
        22
    lambdaq  
       2022-09-28 13:51:04 +08:00
    @1018ji

    举个例子

    import sentry_sdk
    sentry_sdk.utils.strip_string.__defaults__ = (10000,)

    然后再初始化 sentry 的配置。这样你就可以多捕获一些字符过去了。
    1018ji
        23
    1018ji  
       2022-09-28 17:43:56 +08:00
    @lambdaq 感谢大佬
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3117 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 04:53 · PVG 12:53 · LAX 20:53 · JFK 23:53
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.