python有哪些插件_自己动手实现python插件框架(python plugin framework 附源码)

python做为一个动态语言,可以很方便的调用,在程序需要的时候去调用,而且是动态调用的。这为程序开发带来了很大的方便。很多程序都采用了插件式开发,因为方便扩展。在python里,有什么好方法实现插件了,我实现了一个简单的插件:

1. 定义一个插件目录,所有插件都放在这个目录里面。

2. 定义插件要实现的基类,主要是为了插件管理分类方便,python作为动态语言,基类,接口没有太大的意义,因为随时可以扩展。

3. 定义插件管理器,用插件管理器去load 插件

4. 测试调用插件

整个程序目录结构如下(我用pydev做的):

o20121124135124.jpg

iPlugin 是所有插件必须实现的接口,而且里面的name 属性必须定义,插件管理器,根据这个name 去调用插件.#coding:utf-8

class Plugin(object):

""" 定义一个接口,其他 插件必须实现这个接口,name 属性必须赋值 """

name = ''

description = ''

version = ''

def __init__(self):

pass

def executeFun(self):

pass

插件管理器的实现

因为可能有很多种方式管理插件,不同的插件管理器,实现方式不一样,所以定义个插件管理器的基类,各种具体的插件管理器是实现这个基类,比如这里实现了一个 基于目录结构去查找插件的 DirectoryPluginManager

#coding:utf-8

from iPlugin import Plugin

from imp import find_module,load_module,acquire_lock,release_lock

import os

import sys

class PluginManager(object):

"""Base class for plugin managers. Does not implement loadPlugins, so it

may only be used with a static list of plugins.

"""

name = "base"

def __init__(self, plugins=(), config={}):

self.__plugins = []

if plugins:

self.addPlugins(plugins)

def __iter__(self):

return iter(self.plugins)

def addPlugin(self, plug):

print 'PluginManager add plugin:',plug

self.__plugins.append(plug)

def addPlugins(self, plugins):

for plug in plugins:

self.addPlugin(plug)

def delPlugin(self, plug):

if plug in self.__plugins:

self.__plugins.remove(plug)

def delPlugins(self, plugins):

for plug in plugins:

self.delPlugin(plug)

def getPlugins(self,name=None):

plugins = []

print 'self.__plugins:',self.plugins

for plugin in self.__plugins:

print 'plugin.name',plugin.name

if (name is None or plugin.name == name):

plugins.append(plugin)

return plugins

def _loadPlugin(self, plug):

loaded = False

print '******PluginManager _loadPlugin ,',self.plugins

for p in self.plugins:

if p.name == plug.name:

loaded = True

break

if not loaded:

self.addPlugin(plug)

print "%s: loaded plugin %s " % (self.name, plug.name)

def loadPlugins(self):

pass

def _get_plugins(self):

return self.__plugins

def _set_plugins(self, plugins):

self.__plugins = []

self.addPlugins(plugins)

plugins = property(_get_plugins, _set_plugins, None,

"""Access the list of plugins managed by

this plugin manager""")

class DirectoryPluginManager(PluginManager):

"""Plugin manager that loads plugins from plugin directories.

"""

name = "directory"

def __init__(self, plugins=(), config={}):

default_directory = os.path.join(os.path.dirname(__file__),"plugins")

self.directories = config.get("directories", (default_directory,))

print '========DirectoryPlugManager========',plugins

PluginManager.__init__(self, plugins, config)

def loadPlugins(self):

"""Load plugins by iterating files in plugin directories.

"""

plugins = []

print '********Directory directories:',self.directories

for dir in self.directories:

try:

for f in os.listdir(dir):

if f.endswith(".py") and f != "__init__.py":

plugins.append((f[:-3], dir))

except OSError:

print "Failed to access: %s" % dir

continue

fh = None

mod = None

print '********Directory all plugins:',plugins

for (name, dir) in plugins:

try:

acquire_lock()

fh, filename, desc = find_module(name, [dir])

print '********Directory fh,filename,desc:',fh,filename,desc,name

old = sys.modules.get(name)

if old is not None:

# make sure we get a fresh copy of anything we are trying

# to load from a new path

del sys.modules[name]

mod = load_module(name, fh, filename, desc)

finally:

if fh:

fh.close()

release_lock()

if hasattr(mod, "__all__"):

print '********Directory mod __all__:',mod.__all__

attrs = [getattr(mod, x) for x in mod.__all__]

print '********Directory attrs:',attrs

for plug in attrs:

if not issubclass(plug, Plugin):

continue

self._loadPlugin(plug())

在plugin 目录下 写自己的插件,注意必须实现Plugin 接口,并且必须写name属性

#coding:utf-8

import sys

sys.path.append('../')

from iPlugin import Plugin

__all__ = ["FirstPlugin"]

class FirstPlugin(Plugin):

name = "firstPlugin"

version = '0.0.1'

def __init__(self):

Plugin.__init__(self)

def scan(self, config={}):

return "first plugin"

def execFun(self):

return "exec function"

调用插件

通过插件管理器去调用插件,用你自己需要的插件管理器去调用,我这里只实现了一个基于目录结构的。

#coding:utf-8

from pluginManager import DirectoryPluginManager

import os

if __name__=='__main__':

plugin_manager = DirectoryPluginManager()

plugin_manager.loadPlugins()

plugins = plugin_manager.getPlugins("firstPlugin")

print "**"*30

print plugins[0].execFun()

你会发现,DirectoryPluginManager 找到了名字为 firstPlugin 插件,并成功执行了调用,值得注意的是,在所有的 实现的插件里面,我都加入了一个 __all__属性 暴露公开的类,同时在 pluginManager 里面也用到这个属性。

源代码下载:

点击下载此文件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值