python学习心得(5)— Python插件化开发

前言

这年头,仅仅是硬编码的方式已经满足不了项目逇可拓展性,为了实现拓展的功能,考虑使用插件化加载功能来实现

参考

本文中的方法是import实现
以及参考开源python漏洞扫描器中的实现
https://github.com/Lcys/lcyscan
该扫描器通过加载不同的扫描模块,然后开启线程来实现

实现

废话少说,直接上代码

项目结构如下图:
python学习心得(5)— Python插件化开发_第1张图片
定义了一个Plugins包,中间包含了两个插件Plugin1、Plugin2

# Plugin1:
class A(object):

    def __init__(self):
        pass

    def process(self):
        print('Plugin1')
# Plugin2:
class A(object):

    def __init__(self):
        pass

    def process(self):
        print('Plugin2')

实现的功能是动态加载这两个Plugin,并且调用其中的process方法

# TestPlugin:
import os

# 找到Plugins中所有插件名称
def getPlugin(): 
    path = os.path.split(os.path.realpath(__file__))[0]
    plugins = os.listdir(path + '/Plugins/')
    fil = lambda str: (True, False)[str[-3:] == 'pyc' or str.find('__init__.py') != -1]
    return filter(fil, plugins)

if __name__ == "__main__":
    # 遍历所有插件
    for plugin in getPlugin():
        # Get Plugin File Name
        pluginName = os.path.splitext(plugin)[0]  
        # Load Plugin
        plugin = __import__("Plugins." + pluginName, fromlist=[pluginName]) 
        myplugin = getattr(plugin, "A")
        # Get Plugin Object
        p = myplugin() 
        # Invoke Plugin Method
        p.process()     

结果如下:
这里写图片描述

使用imp实现

import imp
import sys

def __import__(name, globals=None, locals=None, fromlist=None):
    # Fast path: see if the module has already been imported.
    try:
        return sys.modules[name]
    except KeyError:
        pass

    # If any of the following calls raises an exception,
    # there's a problem we can't handle -- let the caller handle it.

    fp, pathname, description = imp.find_module(name)

    try:
        return imp.load_module(name, fp, pathname, description)
    finally:
        # Since we may exit via an exception, close fp explicitly.
        if fp:
            fp.close()

可以看出来,import由上述代码实现
根据上述代码,我们继续使用imp来实现,修改主方法如下

if __name__ == "__main__":
    PluginPath = os.getcwd() + '/Plugins/'
    sys.path.append(os.path.split(os.path.realpath(__file__))[0])
    for plugin in getPlugin():
        pluginName = os.path.splitext(plugin)[0]  # Get Plugin File Name
        # plugin = __import__("Plugins." + pluginName, fromlist=[pluginName])  # Load Plugin
        # myplugin = getattr(plugin, "A")
        # p = myplugin()  # Get Plugin Object
        # p.process()    # Invoke Plugin Method/Plugins/'

        fp, pathname, description = imp.find_module(pluginName, [PluginPath])
        try:
            m = imp.load_module(pluginName, fp, pathname, description)
            myplugin = getattr(m, "A")
            p=myplugin()
            p.process()
        except:
            pass

你可能感兴趣的:(python)