Вопрос

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

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)

Теперь ipplugin выглядит следующим образом:

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' не определено”.

Я смотрю на твой пользовательская веб-ссылка где есть дамп IntrospectionHelper.Это очень трудно читать без отступов, но, похоже, вы делаете именно это:

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

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

Это исходный модуль dict, который вы там меняете, а не информационная копия, которую вы собираетесь вернуть!Удалите этих участников из живого модуля, и вы можете ожидать гораздо большего, чем просто разрыв ‘super’.

Очень трудно уследить за тем, что делает этот модуль, но моя реакция такова, что в нем слишком много магии.Среднестатистической программе на Python никогда не нужно возиться с системой импорта, sys.path и элементами модуля monkey-patching __magic__.Немного магии может стать отличным трюком, но это чрезвычайно хрупкое средство.Сразу после просмотра мне пришло в голову, что код может быть взломан такими вещами, как:

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

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

В данном случае сейчас это нет самое время окунуться в импортную магию!Это жесткий.Вместо этого делайте все Обычным способом Python.Возможно, потребуется немного больше текста, чтобы указать в нижней части упаковки. mypackage/__init__.py:

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

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

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

Другие советы

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top