pythonã§ãã©ã°ã¤ã³ç®¡çã®ããã¿ãä½ã£ã¦ã¿ã¾ããã
å æ¥ä½ã£ããã¡ã¤ã«ã³ãã¼ãã¼ã«ã«ãã©ã°ã¤ã³æ©è½ã追å ããæã«ã使ããããªãããã¨æããªãããç°¡æãã©ã°ã¤ã³ç®¡çã¯ã©ã¹ãä½ã£ã¦ã¿ã¾ããã
ã¯ã©ã¹ã®ååã¯PluginMgrã§ããï¼ãã¾ãã«ãå®æãªååã§ããã©ãããï¼
ãã®PluginMgrã¯ä»¥ä¸ã®ãã¨ãè¡ãã¾ãã
ã»æå®ããããã£ã¬ã¯ããªä¸ãããã¢ã¸ã¥ã¼ã«ãã¤ã³ãã¼ãããã
ã»ã¤ã³ãã¼ãããã¢ã¸ã¥ã¼ã«ããã©ã°ã¤ã³ã¨ãã¦ã®æ¡ä»¶ï¼å¿ è¦ãªé¢æ°ãåå¨ãããã¨ï¼ãæºããã¦ããå ´åã«ã¯
ãã¢ã¸ã¥ã¼ã«ãã¨ã«ãé¢æ°åã¨é¢æ°ãªãã¸ã§ã¯ãã®è¾æ¸ãä½æãã¦ä¿æã
ã½ã¼ã¹ã³ã¼ãã¯ãããªæãã§ãã
# -*- coding: utf-8 -*- import os import sys import inspect # # class PluginMgr: ''' ãã©ã°ã¤ã³ç®¡çããã¼ã¸ã£ã çææã«æå®ããããã©ã°ã¤ã³ãã£ã¬ã¯ããªä¸ããããã©ã°ã¤ã³ãããã³ã« ã«é©åãããã©ã°ã¤ã³ã¢ã¸ã¥ã¼ã«ããã¼ãããã ãã¼ããããã©ã°ã¤ã³ã¢ã¸ã¥ã¼ã«ã«é¢ãã¦ãã¢ã¸ã¥ã¼ã«åãã¢ã¸ã¥ã¼ã«ä¸ã® é¢æ°åã¨é¢æ°ãªãã¸ã§ã¯ããè¾æ¸ã¨ãã¦ä¿æããã ''' def __init__(self, targetDir, pluginFuncs): ''' åæåã targetDir: 管ç対象ã®ãã©ã°ã¤ã³ãã£ã¬ã¯ããªãã¹ã requiredFuncs: ãã©ã°ã¤ã³ãããã³ã«ã«é©åããããã®é¢æ°æ å ±ã®ãªã¹ãã [(é¢æ°å, å¿ é ãã©ã°), ....] å¿ é ãã©ã°ãTrueã«æå®ããã¦ããé¢æ°ã¯ãããã³ã«é©åã®ããã«ã¯å¿ é ã Falseã®ãã®ã¯ããã®é¢æ°ãåå¨ããã°å¼ã³åºããããã¨ã示ãã ''' # ãã©ã°ã¤ã³ãããã³ã«ãã§ãã¯ç¨ãªã¹ã # å¿ é é¢æ°ç¨ãªã¹ã self.requiredFuncNames = # ãã®ä»ã®é¢æ°ç¨ãªã¹ã self.otherFuncNames = # ãããã³ã«é¢æ°æ å ±ã®è¨å® self.set_plugin_funcs(pluginFuncs) # 管çãã£ã¬ã¯ããªãã¹ãåæå self.pluginDirPath = None # ãã©ã°ã¤ã³æ å ±ç¨ã®è¾æ¸ãåæå # {'ã¢ã¸ã¥ã¼ã«å': {é¢æ°å: é¢æ°ãªãã¸ã§ã¯ã, ...}, # 'ã¢ã¸ã¥ã¼ã«å': {é¢æ°å: é¢æ°ãªãã¸ã§ã¯ã, ...}} # ã¨ãã管çæ§é ã¨ãªã£ã¦ããã self.pluginDict = {} # ãã©ã°ã¤ã³ãã£ã¬ã¯ããªã®ç»é² self.set_plugin_dir(targetDir) # ãã¹ãå®åãããã£ã¬ã¯ããªã®å ´åã«ã¯ããã®ä¸ã«åå¨ãããã©ã°ã¤ã³ # ãèµ°æ»ããèªèº«ã®ç®¡çç¨è¾æ¸ã«ç»é²ãã self.load_plugins() def set_plugin_funcs(self, funcs): ''' ãã©ã°ã¤ã³ãããã³ã«ã«é©åããé¢æ°æ¡ä»¶ãè¨å®ããã funcs: ãã©ã°ã¤ã³ãããã³ã«ã«é©åããããã®é¢æ°æ å ±ã®ãªã¹ãã [(é¢æ°å, å¿ é ãã©ã°), ....] Return: None ''' if funcs == None: return # ç¾ç¶ã®æ å ±ãç ´æ£ del self.requiredFuncNames[:] del self.otherFuncNames[:] # å¿ é é¢æ°åããã®ä»ã®é¢æ°åãæ¯ãåãã¦ãã for name, flag in funcs: if flag: self.requiredFuncNames.append(name) else: self.otherFuncNames.append(name) def set_plugin_dir(self, path): ''' ãã¹æååãæ£è¦åãããã©ã°ã¤ã³ãã£ã¬ã¯ããªã¨ãã¦ç»é²ã path: ãã©ã°ã¤ã³ãã£ã¬ã¯ããªã®ãã¹æååã Return: None ''' if path == None or len(path) == 0: return # ãã©ã°ã¤ã³ãã£ã¬ã¯ããªãã¹ãæ£è¦å self.pluginDirPath = os.path.normpath(os.path.expanduser(path)) # 管ç対象ã®ãã©ã°ã¤ã³ãã£ã¬ã¯ããªãã¢ã¸ã¥ã¼ã«ãã¹ã«å«ã¾ã㦠# ããªãå ´åã«ã¯è¿½å ããã if self.pluginDirPath not in sys.path: sys.path.append(self.pluginDirPath) def load_plugins(self): ''' ãã©ã°ã¤ã³ãã£ã¬ã¯ããªä¸ã®ãã©ã°ã¤ã³ããã¼ããã ãã©ã°ã¤ã³ã®ãããã³ã«ãã§ãã¯ãééãããã®ã®ã¿ã èªèº«ã®ç®¡çç¨è¾æ¸ã«è¿½å ããã Return: None ''' if self.pluginDirPath == None: return if os.path.isdir(self.pluginDirPath) == False: return # ãã©ã°ã¤ã³ç®¡çç¨è¾æ¸ãã¯ãªã¢ self.pluginDict.clear() # ãã©ã°ã¤ã³ãã£ã¬ã¯ããªä¸ã®ãã¡ã¤ã«ã調ã¹ããã©ã°ã¤ã³ãããã³ã«ã« # é©åããã¢ã¸ã¥ã¼ã«ã®æ å ±ãæ§ç¯ããã for item in os.listdir(self.pluginDirPath): if os.path.isfile(item) != False: continue modName = inspect.getmodulename(item) funcInfoDict = self.import_plugin(modName) if funcInfoDict: self.pluginDict[modName] = funcInfoDict def import_plugin(self, modName): ''' ãã©ã°ã¤ã³ãããã³ã«ã«ä¸è´ããã¯ã©ã¹ãã¢ã¸ã¥ã¼ã«ããã¤ã³ãã¼ãããã modName: ã¢ã¸ã¥ã¼ã«åæååã Return: è¾æ¸ã {é¢æ°å: é¢æ°ãªãã¸ã§ã¯ã, ....} ã¢ã¸ã¥ã¼ã«åãä¸æ£ãªå ´åããã©ã°ã¤ã³ãããã³ã«ã«é©åããªãã£ã å ´åã«ã¯Noneãè¿ãããã ''' if modName == None or len(modName) == 0: return None # ã¢ã¸ã¥ã¼ã«ãã¤ã³ãã¼ã try: mod = __import__(modName) except: print 'error on importing %s' % modName return None # ã¢ã¸ã¥ã¼ã«ããã¯ã©ã¹å±æ§ããã¤ãªãã¸ã§ã¯ããåå¾ããã funcList = inspect.getmembers(mod, inspect.isfunction) if funcList == None or len(funcList) == 0: return None # å¿ é ã®é¢æ°ãåå¨ããªãå ´åã«ã¯ãã®ã¢ã¸ã¥ã¼ã«ã¯ # ãããã³ã«ã«å¯¾å¿ãã¦ããªãã¨å¤å®ããå¦çãä¸æã # (ãã®ã¢ã¸ã¥ã¼ã«ã®é¢æ°æ å ±ã¯ä½æããªã) funcNames = [item[0] for item in funcList] for fname in self.requiredFuncNames: if fname not in funcNames: return None # ã¢ã¸ã¥ã¼ã«å ã®é¢æ°ã®ãã¡ããããã³ã«é©åæ¡ä»¶ã¨ã㦠# ç»é²ããã¦ããé¢æ°ã«ã¤ãã¦ã®ã¿æ å ±ãç»é²ããã # (ãããã³ã«ã«ç¡é¢ä¿ãªé¢æ°ãªãã¸ã§ã¯ãã¯ç¡è¦ãã) funcDict = {} for name, funcObj in funcList: if (name not in self.requiredFuncNames and name not in self.otherFuncNames): continue funcDict[name] = funcObj return funcDict def get_plugin_count(self): ''' ç»é²ããã¦ãããã©ã°ã¤ã³æ°ãåå¾ããã Return: æ´æ°ããã©ã°ã¤ã³ã¢ã¸ã¥ã¼ã«æ°ã ''' return len(self.pluginDict) def get_plugin_names(self): ''' ç»é²ããã¦ãããã©ã°ã¤ã³åã®ãªã¹ããåå¾ããã Return: ãªã¹ãã [ã¢ã¸ã¥ã¼ã«å, ...] ''' return self.pluginDict.keys() def get_plugin_funcs(self, modName): ''' ãã©ã°ã¤ã³ã¢ã¸ã¥ã¼ã«åï¼æååï¼ãæå®ãã¦ããã®ã¢ã¸ã¥ã¼ã« ã®ãã©ã°ã¤ã³é¢æ°æ å ±ãåå¾ããã modName: ã¢ã¸ã¥ã¼ã«åæåå return: ãªã¹ãã [(é¢æ°å, é¢æ°ãªãã¸ã§ã¯ã), ...] ''' if modName == None: return None if modName not in self.pluginDict: return None return self.pluginDict[modName] # # åä½ãã¹ã # def test_plugin_mgr(dirpath, funcs): # ãã©ã°ã¤ã³ããã¼ã¸ã£ãçæ mgr = PluginMgr(dirpath, funcs) # # çæãããã©ã°ã¤ã³ããã¼ã¸ã£ã®æ å ±ãç¢ºèª # print '------------------------' print 'plugin module count : %d' % mgr.get_plugin_count() for name in mgr.get_plugin_names(): print 'name: %s' % name funcDict = mgr.get_plugin_funcs(name) for funcName, funcObj in funcDict.iteritems(): print '\t%s(...): %s' % (funcName, funcObj) if __name__ == '__main__': # ãã©ã°ã¤ã³ãããã³ã«ã«é©åããé¢æ°ã®æ¡ä»¶ãæºå funcs = [('initialize', False), ('terminate', False), ('get_name', True), ('get_description', False), ('get_version', True), ('execute', True)] # æ£å¸¸ç³» test_plugin_mgr('./plugins', funcs) # ãã£ã¬ã¯ããªãã¹ãä¸æ£ test_plugin_mgr('./aaa', funcs) # ãã©ã°ã¤ã³ãããã³ã«é¢æ°ãªã¹ããä¸æ£ test_plugin_mgr('./plugins', None) test_plugin_mgr('./plugins', [])
ä¸è¨ã®ã½ã¼ã¹ã³ã¼ããå®è¡ãã¦ã¿ãã¨ã次ã®ããã«ãªãã¾ããã
ä»åã¯ãåãã¦inspectã¨ããã¢ã¸ã¥ã¼ã«ã使ãã¾ããã
ãã®ã¢ã¸ã¥ã¼ã«ã¯ãpythonã®ã¹ã¯ãªããã¢ã¸ã¥ã¼ã«ä¸ããã¯ã©ã¹ãé¢æ°ãªã©ãä»»æã«åãåºããã¨ãã§ãã¾ãã
inspectã使ãã°ãããªãã³ã¼ããæ¸ãããã®ã§ä¾¿å©ã ãªã¨æãã¾ããã
ãã¦ãã¦ãPluginMgrãä½ã£ãã®ã¯ããã§ããããããã©ã使ã£ã¦ããããããã¾ã èãã¦ã¾ããï¼ç¬
åãªãå®é¨ã§çµãããªããã°ãããã©ãªãããã¨æã£ã¦ã¾ããï¼ç¬