Проблема с использованием супер (Python 2.5.2) - PullRequest
2 голосов
/ 05 марта 2009

Я пишу систему плагинов для своей программы, и я не могу пройти мимо одной вещи:

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

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

Ответы [ 2 ]

20 голосов
/ 05 марта 2009

‘супер’ является встроенным. Если вы не пытались удалить встроенные функции, вы не должны видеть, что «глобальное имя« 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 никогда не нужно возиться с членами модуля import system, sys.path и monkey-patching __magic__. Немного магии может быть изящной уловкой, но это чрезвычайно хрупко. Не смотря на то, что он просматривается, код может быть взломан такими вещами, как:

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

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

В этом случае сейчас не время погружаться в магию импорта! Это трудно . Вместо этого делайте вещи Нормальным Путем Питона. Это может быть немного больше, чтобы напечатать в нижней части пакета mypackage / __ init__.py:

from mypackage import fooplugin, barplugin, bazplugin
plugins= [fooplugin.FooPlugin, barplugin.BarPlugin, bazplugin.BazPlugin]

но это будет работать и быть понятым везде, не полагаясь на гнездо сложной, хрупкой магии.

Кстати, если вы не планируете какую-то углубленную работу по множественному наследованию (и опять же, сейчас, возможно, не время для этого), вам, вероятно, даже не нужно использовать super (). Обычный метод «IPlugin .__ init __ (self, ...)» для вызова известного суперкласса является простым делом; super () не всегда «более новый, лучший способ сделать что-то», и есть вещи, которые вы должны понять об этом , прежде чем приступить к его использованию.

0 голосов
/ 05 марта 2009

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

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

...