动态载入, import 之类的有什么轮子吗? - 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
LeeReamond

动态载入, import 之类的有什么轮子吗?

  •  
  •   LeeReamond Mar 11, 2023 2718 views
    This topic created in 1176 days ago, the information mentioned may be changed or developed.

    需要实现的效果,比如一个服务在跑,然后服务依赖 n 个插件,插件放在单独一个文件夹里,每一个文件对应一个插件,插件随时可以变化,主体服务希望能不重启直接动态载入新代码这样

    印象里多年前研究过这个功能,是可以实现的,但是好像有些麻烦。有什么现成的轮子吗?

    11 replies    2023-03-14 09:51:51 +08:00
    noqwerty
        1
    noqwerty  
       Mar 11, 2023
    可以直接用 importlib 实现: https://docs.python.org/3/library/importlib.html
    learningman
        2
    learningman  
       Mar 11, 2023
    加载用 importlib 是可以搞的,但是清除旧的非常麻烦
    ClericPy
        3
    ClericPy  
       Mar 11, 2023
    我刚做了一个类似的...

    假装是个动态脚本的 RPC, 通过 URL route 选择模块路径, 比如类似格式和很多常见模块的 entrypoint 一样, package.module:function 的方式, 传参兼容 params 和 Post form 以及 post JSON 多种方式, 目前参数只支持 kwargs 直接塞函数 **kwargs 里, 之后会根据 inspect 提取函数参数列表来做 validate 相关以及自动生成表单

    然后动态载入刷新代码什么的, 我是每隔一段时间或者用 watchfile 的方式查看文件变化就从 sys.modules 里删掉, 下次导入就是新的代码了, 以前想过太多 reload 的用法, 发现最简单的就是直接删掉旧的...

    这套东西还没时间开源, 难度不大自己琢磨琢磨也就明白了
    LeeReamond
        4
    LeeReamond  
    OP
       Mar 11, 2023
    @ClericPy 你的意思是用 insepect 监控代码有没有变化,有就删掉旧的,然后每个插件用某种特定方式命名这种感觉?
    ClericPy
        5
    ClericPy  
       Mar 11, 2023   1
    @LeeReamond

    什么啊... inspect 查看函数入参类型的, pydantic 做校验, 类型错误就不执行了

    监控变化用 watchdog 看文件变化, 删掉的逻辑是你只要导入过的模块一般 sys.modules 里面 del 掉, 再导入一次就是新代码了, 不用特定命名, 只要 import path 固定一个目录, 会自动去搜模块名字的. 我那个格式是 URL 路径的格式, 不是命名格式

    如果不放心害怕有篡改文件或者有人偷偷注入什么东西, 我之前还想了做对整个 .py 文件加盐哈希然后哈希值放到文件第一行, 到时候导入前先判断文件对不对
    lolizeppelin
        6
    lolizeppelin  
       Mar 12, 2023
    有, openstack 出品 stevedore

    但必须按标准写 python setup.py,生成 egg 文件

    总之就是符合 pkg_resources 那套标准
    lolizeppelin
        7
    lolizeppelin  
       Mar 12, 2023
    哦 看错了不好意思...
    featureoverload
        8
    featureoverload  
       Mar 13, 2023
    不是有特殊需求的软件,就实现 os.fork+importlib.import_module 好了。这种应该是最简单的
    featureoverload
        9
    featureoverload  
       Mar 13, 2023
    @featureoverload 这种应该是最简单的机制了。

    有内存数据(变量 /对象 /数据结构)交换的话,就使用 multiprocessing+importlib.import_module 可以解决。
    LeeReamond
        10
    LeeReamond  
    OP
       Mar 13, 2023
    @featureoverload fork 在这里是干什么用的呢
    featureoverload
        11
    featureoverload  
       Mar 14, 2023
    @LeeReamond 原本的程序(父进程)负责主 /核心逻辑,比如判断动态导入等。

    在需要动态导入的时候,以及动态导入之后(使用导入的模块)做的事情,在 fork 出来的程序处理。

    这样 [动态导入做的事情] 完成之后,fork 出来的程序(子进程)就让它自己结束--进程销毁;

    ------

    这样就是“业务逻辑”和“核心逻辑”分离,包括进程内的一切变量等等。

    核心逻辑控制什么时候动态导入,业务逻辑实际执行导入和业务行为。
    About     Help     Advertise     Blog &nsp;   API     FAQ     Solana     2795 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 40ms UTC 07:44 PVG 15:44 LAX 00:44 JFK 03:44
    Do have faith in what you're doing.
    ubao msn 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