2009-03-04 2 views
2

Я пишу систему плагинов для моей программы, и я не могу получить за одну вещь:Проблемы с использованием супер (питон 2.5.2)

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 работа flawlessy ими сами, но при вызове ThingLoader прог барабан получает исключение:

File "./plugins\TestPlugin.py", line 13, in __init__ 
    super(TestPlugin, self).__init__(loader) NameError: 
global name 'super' is not defined 

Я посмотрел вокруг, и я просто не знаю, что происходит.

+0

После прочтения принятого ответа у меня возникает соблазн уменьшить вопрос о том, что он неполный и вводящий в заблуждение. –

ответ

20

«супер» - это встроенное средство. Если вы не удалились, чтобы удалить встроенные функции, вы никогда не должны видеть, что «глобальное имя« супер »не определено».

Я смотрю на ваш 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__. Немного волшебства может быть аккуратным трюком, но это очень хрупко. Только от верхней части головы от просмотра его, код может быть разорван такими вещами, как:

  • именами столкновения с модулями верхнего уровня
  • любого использование новых классов
  • модулей поставляются только как скомпилирован байткодом
  • zipimporter

с невероятно круглыми о функциях как getClassDefinitions, extractModuleNames и isFromBase, он смотрит на меня, как вы до сих пор совсем немного, чтобы узнать об основах ч ow Python работает. (Ключи: getattr, module .__ name__ и issubclass, соответственно.)

В данном случае не время для погружения в магию импорта! Это hard. Вместо этого делайте вещи «Обычный Путь Питона». Это может быть немного больше, набрав сказать, в нижней части 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, прежде чем вы начнете заряжать его.

+2

+1 для фактического перехода по ссылке на страницу пользователя, чтобы найти копию кода, а затем отладить его. Это должен быть один из наиболее тщательно изученных ответов. – DNS

+0

Он должен получить приз от этого! – Diones

+0

Должно быть, было очень приятно написать этот ответ. +1 – nosklo

0

Если вы используете версию Python раньше 2.2 (довольно маловероятно), super() определенно является built-in function (доступен в любой области и без импорта чего-либо).

Возможно, стоит проверить вашу версию Python (просто запустите интерактивное приглашение, набрав python в командной строке).

Смежные вопросы