ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

如何实现可热拔插的插件系统

2022-03-09 23:32:24  阅读:190  来源: 互联网

标签:文件 插件 plugin py 系统 parse 可热拔 import example


设想有这样一个场景:爬虫把数据一条一条写入到 Redis 中,你的另一个程序从 Redis 中一条条读取出来,进行一些处理后写入 MongoDB。

一开始,你的处理逻辑非常简单,如果爬虫爬取的数据中,包含“垃圾信息”这四个字,那么直接把信息丢弃。

运行了一段时间,新增了一个需求:如果数据的“source”字段为weibo并且包含“过时信息”,那么把数据丢弃。

又过了一段时间,老板又来了一个需求:如果数据的"source"字段为“bilibili”,并且正文包含“报警”,那么调用一个报警接口,通知老板。但数据继续走后续流程。

按照常规做法,每次增加新的需求,你都要改项目代码,然后重新启动程序。

现在,我们想实现一个插件系统,整个项目始终不停运行,这些新增的需求通过一个一个插件文件来完成,每完成一个需求,把这个文件放到某个特定的文件夹里面,系统自动就会开始调用。

所谓的“插件系统”,看起来非常高大,实际上非常简单,我们的主程序定期扫描特定文件夹,如果发现新增文件或者有文件发生了修改,就热加载这个文件中的代码。

在 Python 里面,我们可以使用importlib.reload函数来重新加载一个模块。我们来看一下它的用法。

首先,我们创建一个文件example_plugin.py,里面的内容如下:

def parse():
    print('初始数据')

然后,我们创建一个main.py文件,来调用它:

import importlib
import example_plugin

example_plugin.parse()
input('修改完成数据以后回来按下回车键:')
importlib.reload(example_plugin)
example_plugin.parse()

程序运行到input这一行时,会停下来。然后我们去修改example_plugin.py中,parse函数中的代码,修改完成以后保存。回到终端里面按下回车。运行效果如下图所示:

如果 example_plugin.py 在一个package 里面,也没有问题,如下图所示结构:

只不过是在main.py中,把导入模块的代码改成了from package import module而已。

但需要注意的是,reload函数的作用对象是一个module,也就是xxx.py文件。所以如果你试图像下面这样写代码,必然会出问题:

import importlib
from plugin.example_plugin import parse

parse()
importlib.reload(parse)  #这里一定会出问题
parse()

还有一种非常容易让人混淆的情况,那就是如果example_plugin.py中的函数也叫做example_plugin,然后在__init__中提前导入:from example_plugin import example_plugin,那么此时当你在 main.py中执行from plugin import example_plugin时,导入的实际上是example_plugin函数,而不是 module。如下图所示:

 

 

最后,如果你使用 PyCharm 来测试,可能会发现你修改了文件,但是热加载却失败了。这是因为 PyCharm 在改了文件以后,不是实时写到硬盘上的,它有一个缓存时间。当你修改了一个文件以后,你可以使用另一个程序打开一下这个被修改的文件,这样缓存到 PyCharm 中的修改内容就会被真正写到文件里面去。

这就是实现热加载的核心功能了。基于importlib.reload,你可以写一段代码,监控某个特定的文件夹,一旦发现里面新增、修改、删除文件,你就把这些变动的代码热加载一次。然后正在运行中的 Python 程序就可以不停机使用新增的功能了。

 

转自:微信公众号:未闻code

标签:文件,插件,plugin,py,系统,parse,可热拔,import,example
来源: https://www.cnblogs.com/tjp40922/p/15987643.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有