Pregunta

Estoy escribiendo un sistema de complementos para mi programa y no puedo pasar de una cosa:

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

El complemento de prueba se ve así:

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)

Ahora el IPlugin se ve así:

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

Todas las clases de IPlugin funcionan perfectamente por sí mismas, pero cuando ThingLoader las llama, el programa obtiene una excepción:

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

Miré a mi alrededor y simplemente no sé qué está pasando.

¿Fue útil?

Solución

& # 8216; super & # 8217; es un builtin. A menos que haya hecho todo lo posible para eliminar elementos incorporados, nunca debería ver que & # 8220; el nombre global 'super' no está definido & # 8221 ;.

Estoy viendo su enlace web del usuario donde hay un volcado de IntrospectionHelper. Es muy difícil de leer sin la sangría, pero parece que puedes estar haciendo exactamente eso:

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

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

Ese es el dictamen original del módulo que está cambiando allí, ¡no una copia informativa que está a punto de devolver! Elimine estos miembros de un módulo en vivo y puede esperar mucho más que & # 8216; super & # 8217; para romper.

Es muy difícil hacer un seguimiento de lo que está haciendo ese módulo, pero mi reacción es que hay demasiada magia en él. El programa Python promedio nunca debería tener que estar jugando con el sistema de importación, sys.path y los miembros del módulo __magic__ de parcheo de monos. Un poco de magia puede ser un buen truco, pero esto es extremadamente frágil. Justo en la parte superior de mi cabeza de buscarlo, el código podría ser roto por cosas como:

  • el nombre choca con los módulos de nivel superior
  • cualquier uso de clases de nuevo estilo
  • módulos suministrados solo como código de bytes compilado
  • zipimporter

Desde las funciones increíblemente completas como getClassDefinitions, extractModuleNames y isFromBase, me parece que todavía tienes bastante que aprender sobre los conceptos básicos de cómo funciona Python. (Pistas: getattr, module .__ name__ y issubclass, respectivamente.)

En este caso, ahora no es el momento de sumergirse en la magia de importación. Es difícil . En su lugar, hacer cosas de la manera normal de Python. Puede ser un poco más de escritura al final del paquete de paquetes / __ init__.py:

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

pero funcionará y se entenderá en todas partes sin depender de un nido de magia compleja y frágil.

Por cierto, a menos que esté planeando realizar un trabajo de herencia múltiple en profundidad (y, nuevamente, puede que ahora no sea el momento para eso), es probable que ni siquiera necesite usar super (). El habitual & # 8220; IPlugin .__ init __ (self, ...) & # 8221; el método de llamar a una superclase conocida es lo más sencillo que se debe hacer; super () no siempre es & # 8220; la forma más nueva y mejor de hacer las cosas & # 8221; y hay cosas que debe entender al respecto antes de comenzar a utilizarlo.

Otros consejos

A menos que esté ejecutando una versión de Python anterior a la 2.2 (muy poco probable), super () es definitivamente un función incorporada (disponible en todos los ámbitos, y sin importar nada).

Puede valer la pena revisar tu versión de Python (solo inicia el indicador interactivo al escribir python en la línea de comandos).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top