这年头,仅仅是硬编码的方式已经满足不了项目逇可拓展性,为了实现拓展的功能,考虑使用插件化加载功能来实现
本文中的方法是import实现
以及参考开源python漏洞扫描器中的实现
https://github.com/Lcys/lcyscan
该扫描器通过加载不同的扫描模块,然后开启线程来实现
废话少说,直接上代码
项目结构如下图:
定义了一个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()
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