我正在为我的程序编写一个插件系统,但我不能忘记一件事:
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
测试插件如下所示:
^{pr2}$现在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
我环顾四周,根本不知道发生了什么。在
除非您运行的Python版本早于2.2(不太可能),否则
super()
绝对是{a1}(在每个范围内都可用,并且不导入任何内容)。在可能值得检查一下Python的版本(只需在命令行键入Python启动交互式提示)。在
“超级”是一个内置的。除非您特意删除了内置项,否则您永远不会看到“global name‘super’is not defined”。在
我在看你的user web link,那里有一堆自省助手。如果没有缩进,很难阅读,但看起来你可能正是这样做的:
这是您要更改的原始模块dict,而不是您要返回的信息副本!从一个活动模块中删除这些成员,你就可以期待更多的“超级”破坏。在
很难跟踪那个模块在做什么,但我的反应是其中有太多的魔力。一般的Python程序不应该在导入系统上乱搞,搜索路径和猴子修补魔术模块成员。一点点魔法可以是一个巧妙的把戏,但这是极其脆弱的。在我浏览它的时候,代码可能会被如下内容破坏:
从getClassDefinitions、ExtractModuleName和isFromBase等函数开始,在我看来,您仍有相当多的内容需要了解Python的基本原理。(线索:getattr、module.\uu name_uu和issubclass)
在这种情况下,现在是而不是潜入进口魔法的时候了!这很难。相反,用普通的Python方法来做。在一个包的mypackage/\uu init_uu.py的底部,可能需要输入更多的内容:
^{pr2}$但它将在任何地方发挥作用并被理解,而不需要依赖于一堆复杂而脆弱的魔法。在
顺便说一句,除非您计划进行一些深入的多重继承工作(再说一次,现在可能不是进行此工作的时候),否则您可能根本不需要使用super()。调用已知超类的通常的“IPlugin.\uu init_uu(self,…)”方法是很简单的;super()并不总是“更新、更好的方法”和there are things you should understand about it,然后再开始使用它。在
相关问题 更多 >
编程相关推荐