使用超级问题(python 2.5.2)
-
03-07-2019 - |
题
我正在为我的程序编写一个插件系统,但我无法克服一件事:
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
我环顾四周,根本不知道发生了什么。
解决方案
‘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 和猴子修补 __magic__ 模块成员。一点点魔法可能是一个巧妙的技巧,但这非常脆弱。浏览代码后,我突然想到,代码可能会被以下因素破坏:
- 名称与顶级模块冲突
- 任何新式类的使用
- 仅作为编译字节码提供的模块
- zip导入器
从 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() 并不总是“更新、更好的做事方式”并且 有些事情你应该了解 在您开始充电使用它之前。
其他提示
除非您运行的是早于2.2的Python版本(非常不可能),否则 super()
肯定是内置函数(适用于所有范围,无需导入任何内容)。
可能值得检查你的Python版本(只需在命令行输入python启动交互式提示)。