我正在为我的程序编写一个插件系统,我无法解决一件事:
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#prints <class 'TestPlugin.TestPlugin'>
foo(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
我环顾四周,我根本不知道发生了什么。
答案 0 :(得分:20)
'super'是内置的。除非你不顾一切地删除内置函数,否则你不应该看到“全局名称'super'未定义”。
我正在看你的user web link那里有一个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__模块成员。一点点魔法可以是一个巧妙的技巧,但这是非常脆弱的。只是在浏览它之后,代码可能被以下内容破坏:
从getClassDefinitions,extractModuleNames和isFromBase这些令人难以置信的圆形函数中,我觉得你仍然需要了解Python工作原理的基础知识。 (线索:getattr,模块.__ name__和issubclass。)
在这种情况下现在是不潜入进口魔术的时间!这是很难。相反,做正常的Python方式。在包的mypackage / __ init __的底部说一下可能会多一点打字.py:
from mypackage import fooplugin, barplugin, bazplugin
plugins= [fooplugin.FooPlugin, barplugin.BarPlugin, bazplugin.BazPlugin]
但它会起作用并且在任何地方都能被理解,而不依赖于一堆复杂,脆弱的魔法。
顺便说一下,除非你计划进行一些深入的多重继承工作(现在可能不是时候了),你甚至可能不需要使用super()。调用已知超类的通常的“IPlugin .__ init __(self,...)”方法是直截了当的事情;在你开始使用它之前,super()并不总是“更新,更好的做事方式”和there are things you should understand about it。
答案 1 :(得分:0)
除非您运行的是早于2.2的Python版本(非常不可能),super()
绝对是built-in function(在每个范围内都可用,并且不会导入任何内容)。
可能值得检查你的Python版本(只需在命令行输入python启动交互式提示)。