返回顶部
首页 > 资讯 > 后端开发 > Python >Python中实现简单的插件框架
  • 671
分享到

Python中实现简单的插件框架

插件框架简单 2023-01-30 23:01:57 671人浏览 薄情痞子

Python 官方文档:入门教程 => 点击学习

摘要

在系统设计中,经常我们希望设计一套插件机制,在不修改程序主体情况下,动态去加载附能。 我设想的插件系统: 1、通过类来实现 2、自动查找和导入 我们假设需要实现一个简单的插件系统,插件可以接收一个参数执行。 实现基础插件类 我们先构建一

在系统设计中,经常我们希望设计一套插件机制,在不修改程序主体情况下,动态去加载附能。

plugin

我设想的插件系统:

1、通过类来实现
2、自动查找和导入

我们假设需要实现一个简单的插件系统,插件可以接收一个参数执行。

实现基础插件类

我们先构建一个基础插件类:plugin_collection.py

class Plugin:
    """
    该基类每个插件都需要继承,插件需要实现基类定义的方法"""
    def __init__(self):
        self.description = '未知'

    def perfORM_operation(self, argument):
        """
        实际执行插件所执行的方法,该方法所有插件类都需要实现
        """
        raise NotImplementedError

所有的插件类需要申明description来进行插件描述,并且要实现perform_operation方法,该方法是实际加载插件将去执行的方法。

简易插件

我们现在实现一个插件,实际执行时仅返回传入的参数: plugins/identity.py

import plugin_collection

class Identity(plugin_collection.Plugin):
    """
    This plugin is just the identity function: it returns the argument
    """
    def __init__(self):
        super().__init__()
        self.description = 'Identity function'

    def perform_operation(self, argument):
        """
        The actual implementation of the identity plugin is to just return the
        argument
        """
        return argument

动态加载机制

因为我们预实现动态加载插件。我们通过定义一个PluginCollection来完成该职责,它将载入所有的插件,并且根据传入的值执行perform_operation方法。PluginCollection类基础组件实现如下:plugins_collection.py

class PluginCollection:
    """
    该类会通过传入的package查找继承了Plugin类的插件类
    """
    def __init__(self, plugin_package):
        self.plugin_package = plugin_package
        self.reload_plugins()

    def reload_plugins(self):
        """
        重置plugins列表,遍历传入的package查询有效的插件
        """
        self.plugins = []
        self.seen_paths = []
        print()
        print(f"在 {self.plugin_package} 包里查找插件")
        self.walk_package(self.plugin_package)

    def apply_all_plugins_on_value(self, argument):
        print()
        print(f"执行参数 {argument} 到所有的插件:")
        for plugin in self.plugins:
            print(f"    执行 {plugin.description} 参数 {argument} 结果 {plugin.perform_operation(argument)}")

最关键的是PluginCollection类里的walk_package方法,该方法按如下步骤操作:

1、操作package里所有的模块
2、针对找到的模块,检查是否是Plugin的子类,非Plugin自身。每个插件将会初始化并加入到列表。该检查的好处是你可以放入其他python模块,也并不影响插件的使用
3、检查当前package下的子目录,递归查找插件

    def walk_package(self, package):
        """
        递归遍历包里获取所有的插件
        """
        imported_package = __import__(package, fromlist=['blah'])
        
        for _, pluginname, ispkg in pkgutil.iter_modules(imported_package.__path__, imported_package.__name__ + '.'):
            if not ispkg:
                plugin_module = __import__(pluginname, fromlist=['blah'])
                clsmembers = inspect.getmembers(plugin_module, inspect.isclass)
                for (_, c) in clsmembers:
                    # 仅加入Plugin类的子类,忽略掉Plugin本身
                    if issubclass(c, Plugin) and (c is not Plugin):
                        print(f'    找到插件类: {c.__module__}.{c.__name__}')
                        self.plugins.append(c())
    
        # 现在我们已经查找了当前package中的所有模块,现在我们递归查找子packages里的附件模块
        all_current_paths = []
        if isinstance(imported_package.__path__, str):
            all_current_paths.append(imported_package.__path__)
        else:
            all_current_paths.extend([x for x in imported_package.__path__])
        
        for pkg_path in all_current_paths:
            if pkg_path not in self.seen_paths:
                self.seen_paths.append(pkg_path)
    
                # 获取当前package中的子目录
                child_pkgs = [p for p in os.listdir(pkg_path) if os.path.isdir(os.path.join(pkg_path, p))]
    
                # 递归遍历子目录的package
                for child_pkg in child_pkgs:
                    self.walk_package(package + '.' + child_pkg)

测试

现在我们写个简单的测试:test.py

from plugin_collection import PluginCollection

my_plugins = PluginCollection('plugins')
my_plugins.apply_all_plugins_on_value(5)

执行结果:

$ python3 test.py 

在 plugins 包里查找插件
    找到插件类: plugins.identity.Identity

执行参数 5 到所有的插件:
    执行 Identity function 参数 5 结果 5

代码:https://GitHub.com/erhuabushuo/plugin_template

--结束END--

本文标题: Python中实现简单的插件框架

本文链接: https://www.lsjlt.com/news/181186.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Python中实现简单的插件框架
    在系统设计中,经常我们希望设计一套插件机制,在不修改程序主体情况下,动态去加载附能。 我设想的插件系统: 1、通过类来实现 2、自动查找和导入 我们假设需要实现一个简单的插件系统,插件可以接收一个参数执行。 实现基础插件类 我们先构建一...
    99+
    2023-01-30
    插件 框架 简单
  • 使用Python实现简单的爬虫框架
    目录一、请求网页二、解析 HTML三、构建爬虫框架爬虫是一种自动获取网页内容的程序,它可以帮助我们从网络上快速收集大量信息。在本文中,我们将学习如何使用 Python 编写一个简单的...
    99+
    2023-05-19
    Python如何实现爬虫框架 Python爬虫框架 Python爬虫
  • python实现一个简单的web应用框架
    目录引言写应用框架需要写底层服务器么uwsgi基本使用安装uwsgi配置uwsgiuwsgi常用配置uwsgi启服和停服启动一个demo写一个简单的web应用框架总结引言 本篇文章所...
    99+
    2023-05-18
    python web应用框架 python web
  • .Net插件框架ManagedExtensibilityFramework简介
    Managed Extensibility Framework(MEF)是微软的一个用来扩展.NET应用程序的框架,它最初为了满足Visual Studio里的编辑器的需求,比如说,...
    99+
    2024-04-02
  • SpringIOC框架的简单实现步骤
    目录简单介绍具体实现首先,咱们先配置一下相关的jar包(pom.xml)创建一个Pet接口,存放方法say()创建一个Person类创建一个Dog类,继承Pet接口重点来了,配置ap...
    99+
    2024-04-02
  • 怎样实现简单的RPC框架
    怎样实现简单的RPC框架,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。1.定义上下文对象在RpcContext对象中增加一个map类型的参数对象,可以存放任意扩展的参数。2.R...
    99+
    2023-06-04
  • python的简单web框架flask快速实现详解
    目录简介web框架的重要组成部分快速上手flaskflask的第一个应用flask中的路由不同的http方法静态文件使用模板总结简介 python可以做很多事情,虽然它的强项在于进...
    99+
    2023-02-07
    python web框架flask python web框架
  • .NET Core实现简单的Redis Client框架
    目录0,关于RedisRESP1,定义数据类型2,定义异步消息状态机3,定义命令发送模板4,定义RedisClient5,实现简单的RESP解析6,实现命令发送客户端7,如何使用8,...
    99+
    2024-04-02
  • jQuery插件实现简单动画
    本篇内容主要讲解“jQuery插件实现简单动画”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“jQuery插件实现简单动画”吧!jQuery 提供了一系列的动画方...
    99+
    2024-04-02
  • 使用Python的Flask框架表单插件Flask-WTF实现Web登录验证
    表单是让用户与我们的网页应用程序交互的基本元素。Flask 本身并不会帮助我们处理表单,但是 Flask-WTF 扩展让我们在我们的 Flask 应用程序中使用流行的 WTForms 包。这个包使得定义表单...
    99+
    2022-06-04
    表单 插件 框架
  • Swiper.js插件超简单实现轮播图
    Swiper是纯javascript打造的滑动特效插件,面向手机、平板电脑等移动终端。能实现触屏焦点图、触屏Tab切换、触屏多图切换等常用效果。超好用 话不多说,直接上教程 1、首...
    99+
    2024-04-02
  • C#框架winform实现简单点餐系统
    本文实例为大家分享了C#框架winform实现简单点餐系统的具体代码,供大家参考,具体内容如下 一、编程思想 1、构思界面并进行设计 2、思考需要用到的控件以及控件需要更改的属性 3...
    99+
    2024-04-02
  • Eclipse中的Jobs框架的简单介绍
    这篇文章主要讲解了“Eclipse中的Jobs框架的简单介绍”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Eclipse中的Jobs框架的简单介绍”吧!了解Eclipse多线程机制,需要先了...
    99+
    2023-06-17
  • 如何在Python中实现一个简单的RPC远程过程调用框架
    如何在Python中实现一个简单的RPC远程过程调用框架在分布式系统中,一种常见的通信机制是通过RPC(Remote Procedure Call,远程过程调用)来实现不同进程之间的函数调用。RPC允许开发者像调用本地函数一样调用远程函数,...
    99+
    2023-10-27
    远程调用 Python RPC框架 实现RPC
  • scrapy框架的简单介绍
    这篇文章主要介绍“scrapy框架的简单介绍”,在日常操作中,相信很多人在scrapy框架的简单介绍问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”scrapy框架的简单介绍”的疑惑有所帮助!接下来,请跟着小编...
    99+
    2023-06-02
  • Python流行ORM框架sqlalchemy的简单使用
    安装 http://docs.sqlalchemy.org 安装 #进入虚拟环境 #执行 ./python3 -m pip install import sqlalchemy print(sqlalchemy....
    99+
    2022-06-02
    Python ORM框架sqlalchemy
  • .net中的DI框架AutoFac简单介绍
    AutoFac是.net程序下一个非常灵活易用,且功能强大的DI框架,本文这里简单的介绍一下使用方法。 安装: Install-Package Autofac 简单的示例: stat...
    99+
    2024-04-02
  • Go语言Http Server框架实现一个简单的httpServer
    目录实现一个简单地httpServer首先我们来写一个接口基于http库实现一个结构体实现Server接口实现一个简单地httpServer 上一篇文章对http库的基本使用做了说明...
    99+
    2023-05-18
    Go Http Server框架 Go HttpServer
  • Android中网络框架简单封装的实例方法
    Android中网络框架的简单封装 前言 Android作为一款主要应用在移动终端的操作系统,访问网络是必不可少的功能。访问网络,最基本的接口有:HttpUrlConnecti...
    99+
    2022-06-06
    方法 封装 框架 Android
  • Python的Scrapy爬虫框架简单学习笔记
    一、简单配置,获取单个网页上的内容。 (1)创建scrapy项目 scrapy startproject getblog (2)编辑 items.py # -*- coding: utf-8 ...
    99+
    2022-06-04
    爬虫 学习笔记 框架
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作