使用super时出现问题(python 2.5.2)

2024-10-01 09:16:33 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在为我的程序编写一个插件系统,但我不能忘记一件事:

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

我环顾四周,根本不知道发生了什么。在


Tags: fromself程序插件objectfooinitdef
2条回答

除非您运行的Python版本早于2.2(不太可能),否则super()绝对是{a1}(在每个范围内都可用,并且不导入任何内容)。在

可能值得检查一下Python的版本(只需在命令行键入Python启动交互式提示)。在

“超级”是一个内置的。除非您特意删除了内置项,否则您永远不会看到“global name‘super’is not defined”。在

我在看你的user web link,那里有一堆自省助手。如果没有缩进,很难阅读,但看起来你可能正是这样做的:

built_in_list = ['__builtins__', '__doc__', '__file__', '__name__']

for i in built_in_list:
    if i in module.__dict__:
        del module.__dict__[i]

这是您要更改的原始模块dict,而不是您要返回的信息副本!从一个活动模块中删除这些成员,你就可以期待更多的“超级”破坏。在

很难跟踪那个模块在做什么,但我的反应是其中有太多的魔力。一般的Python程序不应该在导入系统上乱搞,搜索路径和猴子修补魔术模块成员。一点点魔法可以是一个巧妙的把戏,但这是极其脆弱的。在我浏览它的时候,代码可能会被如下内容破坏:

  • 名称与顶级模块冲突
  • 是否使用新样式的类
  • 仅作为编译字节码提供的模块
  • zipimporter公司

从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,然后再开始使用它。在

相关问题 更多 >