前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一日一技:如何实现可热拔插的插件系统

一日一技:如何实现可热拔插的插件系统

作者头像
青南
发布2020-04-26 14:49:47
1.8K0
发布2020-04-26 14:49:47
举报
文章被收录于专栏:未闻Code未闻Code

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

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

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

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

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

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

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

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

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

代码语言:javascript
复制
def parse():
    print('初始数据')

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

代码语言:javascript
复制
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文件。所以如果你试图像下面这样写代码,必然会出问题:

代码语言:javascript
复制
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 程序就可以不停机使用新增的功能了。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-04-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 未闻Code 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档