文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Python搭建插件式框架(基于组件开发

2023-01-31 04:41

关注

Python搭建插件式框架(基于组件开发)

概念

基于组件的开发(Component-Based Development,简称CBD)是一种软件开发范型。它是现今软件复用理论实用化的研究热点,在组件对象模型的支持下,通过复用已有的构件,软件开发者可以“即插即用”地快速构造应用软件。

优点

  • 灵活性高:各个功能模块之间的耦合很低,每一个组件都是独立的,它附着在整个插件框架上执行,真正的实现有则加载,无则忽略。

  • 复用性强:由于组件之间的通信或者交互都是通过插件框架提供的接口来执行,各个组件之见是遵守依赖倒置原则的。所以无论需要哪个模块的功能,都只需要将该插件直接拿走复用即可。

框架描述

    之前有这么一个有趣的笑话。说一个人一大早起来想吃火锅,但是他又不想出门,于是他想了个主意,他给A打电话说:今天请大家吃火锅,别的东西都有了,就差一份羊肉了,来的时候带着。完了给B打电话说:今天请大家吃火锅,别的东西都有的,火锅料忘了买了,来的时候捎上……,他用这样的方法将所有的菜凑够,足不出户,就能吃火锅,而且想吃啥就吃啥。

    这个例子中,这个在家里想吃火锅并且挨个给大家打电话的人便是插件式框架中的总框架,本身不提供任何的功能,角色就是总指挥。而小A,小B这些朋友则是各个组件,自己只负责自己的部分,但是每一个组件都无法单独执行,只能在总框架中执行。组件为整个开发提供基本的功能,组件之间的通信也都是通过总框架来实现的,这就是整个插件式框架。

实现

    相信点开看这篇文章的都是有一定Python基础并且遇到类似于插件式开发需求,从而来看一份有用的代码,再将其拷贝走的。话不多说,上代码吧。

目录结构

++PluginFrame

– main.py

– PluginManager

++ Plugins

-- Plugin1.py

-- Plugin2.py

-- Plugin3.py

-- Plugin4.py
### 插件式框架
import os
import sys
from imp import find_module
from imp import load_module

class PluginManager(type):
    #静态变量配置插件路径
    __PluginPath = 'Plugins'

    #调用时将插件注册
    def __init__(self,name,bases,dict):
        if not hasattr(self,'AllPlugins'):
            self.__AllPlugins = {}
        else:
            self.RegisterAllPlugin(self)

    #设置插件路径
    @staticmethod
    def SetPluginPath(path):
        if os.path.isdir(path):
            PluginManager.__PluginPath = path
        else:
            print '%s is not a valid path' % path

    #递归检测插件路径下的所有插件,并将它们存到内存中
    @staticmethod
    def LoadAllPlugin():
        pluginPath = PluginManager.__PluginPath
        if not os.path.isdir(pluginPath):
            raise EnvironmentError,'%s is not a directory' % pluginPath

        items = os.listdir(pluginPath)
        for item in items:
            if os.path.isdir(os.path.join(pluginPath,item)):
                PluginManager.__PluginPath = os.path.join(pluginPath,item)
                PluginManager.LoadAllPlugin()
            else:
                if item.endswith('.py') and item != '__init__.py':
                    moduleName = item[:-3]
                    if moduleName not in sys.modules:
                        fileHandle, filePath,dect = find_module(moduleName,[pluginPath])
                    try:
                        moduleObj = load_module(moduleName,fileHandle,filePath,dect)
                    finally:
                        if fileHandle : fileHandle.close()

    #返回所有的插件
    @property
    def AllPlugins(self):
        return self.__AllPlugins

    #注册插件
    def RegisterAllPlugin(self,aPlugin):
        pluginName = '.'.join([aPlugin.__module__,aPlugin.__name__])
        pluginObj = aPlugin()
        self.__AllPlugins[pluginName] = pluginObj

    #注销插件
    def UnregisterPlugin(self,pLuginName):
        if pluginName in self.__AllPlugins:
            pluginObj = self.__AllPlugins[pluginName]
            del pluginObj

    #获取插件对象。
    def GetPluginObject(self, pluginName = None):
        if pluginName is None:
            return self.__AllPlugins.values()
        else:
            result = self.__AllPlugins[pluginName] if pluginName in self.__AllPlugins else None
            return result

    #根据插件名字,获取插件对象。(提供插件之间的通信)
    @staticmethod
    def GetPluginByName(pluginName):
        if pluginName is None:
            return None
        else:
            for SingleModel in __ALLMODEL__:
                plugin = SingleModel.GetPluginObject(pluginName)
                if plugin:
                    return plugin

#插件框架的接入点。便于管理各个插件。各个插件通过继承接入点类,利用Python中metaclass的优势,将插件注册。接入点中定义了各个插件模块必须要实现的接口。
class Model_Component(object):
    __metaclass__ = PluginManager

    def Start(self):
        print 'Please write the Start() function'

    def ChangeLanguage(self,language):
        print 'Please write the ChangeLanguage() function'

class Model_MenuObj(object):
    __metaclass__ = PluginManager

    def Start(self):
        print 'Please write the Start() function'

    def ChangeLanguage(self,language):
        print 'Please write the ChangeLanguage() function'

class Model_ToolBarObj(object):
    __metaclass__ = PluginManager

    def Start(self):
        print 'Please write the Start() function'

    def ChangeLanguage(self,language):
        print 'Please write the ChangeLanguage() function'

class Model_ParamPanelObj(object):
    __metaclass__ = PluginManager

    def Start(self):
        print 'Please write the Start() function'

    def ChangeLanguage(self,language):
        print 'Please write the ChangeLanguage() function'

__ALLMODEL__ = (Model_ParamPanelObj,Model_ToolBarObj,Model_MenuObj,Model_Component)
#插件1
from PluginManager import Model_MenuObj

class Plugin1(Model_MenuObj):
    def __init__(self):
        pass

    #实现接入点的接口
    def Start(self):
        print "I am plugin1 , I am a menu!"
#插件2
from PluginManager import Model_ToolBarObj

class Plugin2(Model_ToolBarObj):
    def __init__(self):
        pass

    def Start(self):
        print "I am plugin2 , I am a ToolBar!"
#插件3
from PluginManager import Model_ParamPanelObj

class Plugin3(Model_ParamPanelObj):
    def __init__(self):
        pass

    def Start(self):
        print "I am plugin3 , I am a ParamPanel!"
#插件4
from PluginManager import Model_Component

class Plugin4(Model_Component):
    def __init__(self):
        pass

    def Start(self):
        print "I am plugin4 , I am a Component!"
#main调用

import sys
from PluginManager import PluginManager
from PluginManager import __ALLMODEL__

if __name__ == '__main__':
    #加载所有插件
    PluginManager.LoadAllPlugin()

    #遍历所有接入点下的所有插件
    for SingleModel in __ALLMODEL__:
        plugins = SingleModel.GetPluginObject()
        for item in plugins:

            #调用接入点的公共接口
            item.Start()

输出

I am plugin3 , I am a ParamPanel!

I am plugin2 , I am a ToolBar!

I am plugin1 , I am a menu!

I am plugin4 , I am a Component!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯