Question

J'écris un système de plug-in pour mon programme et je ne peux pas dépasser une chose:

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

Le plugin de test ressemble à ceci:

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)

Maintenant, l'IPlugin ressemble à ceci:

class IPlugin(object):
    '''
    classdocs
    '''
    name=''
    def __init__(self, loader):
        self.loader=loader
    def activate(self):
        pass

Toutes les classes IPlugin fonctionnent parfaitement, mais quand elles sont appelées par ThingLoader, le programme obtient une exception:

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

J'ai regardé tout autour et je ne sais tout simplement pas ce qui se passe.

Était-ce utile?

La solution

‘super’ est un construit. Sauf si vous avez essayé de supprimer les éléments intégrés, vous ne devriez jamais voir «le nom global 'super' n'est pas défini».

Je regarde votre lien Web d'utilisateur sur lequel se trouve un vidage d'IntrospectionHelper. Il est très difficile de lire sans l'indentation, mais il semblerait que vous fassiez exactement cela:

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

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

C'est le dicton original du module que vous modifiez ici, pas une copie informative que vous êtes sur le point de renvoyer! Supprimez ces membres d’un module en direct et vous pouvez vous attendre à bien plus que le mot «super».

Il est très difficile de garder une trace de ce que fait ce module, mais ma réaction est qu’elle contient beaucoup trop de magie. Un programme Python moyen ne devrait jamais avoir à s'embarrasser des membres du module import système, sys.path et monkey-patcher __magic__. Un petit peu de magie peut être une astuce intéressante, mais celle-ci est extrêmement fragile. Le code pourrait être cassé par des choses telles que:

  • conflits de noms avec les modules de niveau supérieur
  • toute utilisation de classes de style nouveau
  • modules fournis uniquement en tant que bytecode compilé
  • zipimporter

Parmi les fonctions très circulaires telles que getClassDefinitions, extractModuleNames et isFromBase, il me semble que vous avez encore beaucoup à apprendre sur les bases du fonctionnement de Python. (Indices: getattr, module .__ name__ et issubclass, respectivement.)

Dans ce cas, ce n'est pas le temps de plonger dans la magie de l'importation! C'est difficile . Au lieu de cela, faites les choses à la manière normale de Python. Il est peut-être un peu plus difficile de taper au bas du paquetage / __ init __ du paquet. __: py:

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

mais cela fonctionnera et sera compris partout sans s’appuyer sur un nid de magie complexe et fragile.

Incidemment, à moins que vous ne planifiiez un travail approfondi sur l'héritage multiple (et encore une fois, ce n'est peut-être pas le moment de le faire), vous n'avez probablement même pas besoin d'utiliser super (). La méthode habituelle «IPlugin .__ init __ (self, ...)» consistant à appeler une super-classe connue est une procédure simple à faire. super () n'est pas toujours “la meilleure façon de faire les choses” et vous devez comprendre certaines choses à ce sujet avant de charger en l’utilisant.

Autres conseils

Sauf si vous utilisez une version de Python antérieure à la version 2.2 (assez improbable), super () est définitivement un fonction intégrée (disponible dans toutes les portées, sans rien importer).

Il peut être utile de vérifier votre version de Python (il suffit de lancer l'invite interactive en tapant python sur la ligne de commande).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top