【发布时间】:2011-01-24 21:19:56
【问题描述】:
我正在编写一个应用程序。没有花哨的 GUI:s 或任何东西,只是一个普通的旧控制台应用程序。这个应用程序,我们称之为 App,需要能够在启动时加载插件。所以,很自然,我为插件创建了一个类来继承:
class PluginBase(object):
def on_load(self):
pass
def on_unload(self):
pass
def do_work(self, data):
pass
这个想法是,在启动时,App 将遍历当前目录,包括子目录,搜索包含本身是 PluginBase 子类的类的模块。
更多代码:
class PluginLoader(object):
def __init__(self, path, cls):
""" path=path to search (unused atm), cls=baseclass """
self.path=path
def search(self):
for root, dirs, files in os.walk('.'):
candidates = [fname for fname in files if fname.endswith('.py') \
and not fname.startswith('__')]
## this only works if the modules happen to be in the current working dir
## that is not important now, i'll fix that later
if candidates:
basename = os.path.split(os.getcwd())[1]
for c in candidates:
modname = os.path.splitext(c)[0]
modname = '{0}.{1}'.format(basename, modname)
__import__(mod)
module = sys.modules[mod]
在search 的最后一行之后,我想以某种方式 a) 找到新加载的模块中的所有类,b) 检查这些类中的一个或多个是否是 PluginBase 和 c) 的子类(如果 b ) 实例化那个/那些类并添加到 App 的加载模块列表中。
我尝试了issubclass 和其他人的各种组合,然后是一段激烈的dir:ing 和大约一个小时的恐慌谷歌搜索。我确实找到了一种与我的here 类似的方法,我尝试只是复制粘贴,但得到一个错误,说 Python 不支持按文件名导入,此时我有点失去了注意力,结果,这篇文章是写的。
我在这里无所适从,感谢所有帮助。
【问题讨论】: