我正在为我的程序编写一个插件系统,我无法解决一件事:
class ThingLoader(object): ''' Loader class ''' def loadPlugins(self): ''' Get all the plugins from plugins folder ''' from diones.thingpad.plugin.IntrospectionHelper import loadClasses classList=loadClasses('./plugins', IPlugin)#Gets a list of #plugin classes self.plugins={}#Dictionary that should be filled with #touples of objects and theirs states, activated, deactivated. classList[0](self)#Runs nicelly foo = classList[1] print foo#printsfoo(self)#Raise an exception
测试插件看起来像这样:
import diones.thingpad.plugin.IPlugin as plugin class TestPlugin(plugin.IPlugin): ''' classdocs ''' def __init__(self, loader): self.name='Test Plugin' super(TestPlugin, self).__init__(loader)
现在IPlugin看起来像这样:
class IPlugin(object): ''' classdocs ''' name='' def __init__(self, loader): self.loader=loader def activate(self): pass
所有的IPlugin类都由它们自己完美无缺,但是当被ThingLoader调用时,程序会获得异常:
File "./plugins\TestPlugin.py", line 13, in __init__ super(TestPlugin, self).__init__(loader) NameError: global name 'super' is not defined
我环顾四周,我根本不知道发生了什么.
'super'是内置的.除非你不顾一切地删除内置函数,否则你不应该看到"未定义全局名称'super'".
我正在查看您的用户网站链接,其中有一个IntrospectionHelper转储.没有缩进就很难阅读,但看起来你可能正是这样做的:
built_in_list = ['__builtins__', '__doc__', '__file__', '__name__'] for i in built_in_list: if i in module.__dict__: del module.__dict__[i]
这是原始模块,你在那里改变,而不是你将要返回的信息副本!从实时模块中删除这些成员,你可以期待比"超级"更多的东西.
很难跟踪该模块正在做什么,但我的反应是它有太大的魔力.平均Python程序永远不需要乱搞导入系统,sys.path和monkey-patching __magic__模块成员.一点点魔法可以是一个巧妙的技巧,但这是非常脆弱的.只是在浏览它之后,代码可能被以下内容破坏:
名称与顶级模块冲突
任何使用新式的课程
模块仅作为编译的字节码提供
zipimporter
从getClassDefinitions,extractModuleNames和isFromBase等令人难以置信的全面函数来看,我觉得你仍然需要学习Python工作原理的基础知识.(线索:分别是getattr,module .__ name__和issubclass.)
在这种情况下,现在不是潜入进口魔术的时候了!这很难.相反,做正常的Python方式.在包的mypackage/__ init__.py的底部说一下可能更多的打字:
from mypackage import fooplugin, barplugin, bazplugin plugins= [fooplugin.FooPlugin, barplugin.BarPlugin, bazplugin.BazPlugin]
但它会起作用并且在任何地方都能被理解,而不依赖于一堆复杂,脆弱的魔法.
顺便说一句,除非你计划进行一些深入的多重继承工作(并且现在可能不是时间),你甚至可能不需要使用super().调用已知超类的通常的"IPlugin .__ init __(self,...)"方法是直截了当的事情; super()并不总是"更新,更好的做事方式",在你开始使用之前,你应该了解一些事情.