Domanda

Sto scrivendo un sistema di plugin per il mio programma e non riesco a superare 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

Il plug-in di test è simile al seguente:

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)

Ora IPlugin è simile al seguente:

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

Tutte le classi IPlugin funzionano perfettamente da sole, ma quando vengono chiamate da ThingLoader il programma ottiene un'eccezione:

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

Mi sono guardato intorno e semplicemente non so cosa stia succedendo.

È stato utile?

Soluzione

"super" è incorporato. A meno che tu non abbia fatto di tutto per eliminare i builtin, non dovresti mai vedere "il nome globale 'super' non è definito".

Sto guardando il tuo link web dell'utente dove c'è un dump di IntrospectionHelper. È molto difficile da leggere senza il rientro, ma sembra che tu stia facendo esattamente questo:

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

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

Questo è il modulo originale che stai cambiando lì, non una copia informativa che stai per restituire! Elimina questi membri da un modulo live e puoi aspettarti molto di più di un "super" da interrompere.

È molto difficile tenere traccia di ciò che quel modulo sta facendo, ma la mia reazione è che c'è troppa magia in esso. Il programma Python medio non dovrebbe mai aver bisogno di scherzare con i membri del modulo __magic__ del sistema di importazione, sys.path e patching delle scimmie. Un po 'di magia può essere un trucco, ma questo è estremamente fragile. Appena fuori dalla mia testa dalla navigazione, il codice potrebbe essere rotto da cose come:

  • scontro di nomi con moduli di livello superiore
  • qualsiasi uso di classi di nuovo stile
  • moduli forniti solo come bytecode compilato
  • zipimporter

Dalle funzioni incredibilmente complete come getClassDefinitions, extractModuleNames e isFromBase, mi sembra che tu abbia ancora un po 'di cose da imparare su come funziona Python. (Indizi: getattr, module .__ name__ e issubclass, rispettivamente.)

In questo caso ora non è il momento di immergerti nella magia delle importazioni! È difficile . Invece, fai le cose in modo normale. Potrebbe essere un po 'più di battitura da dire in fondo al mypackage di un pacchetto / __ init__.py:

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

ma funzionerà e sarà compreso ovunque senza fare affidamento su un nido di magia complessa e fragile.

Per inciso, a meno che tu non stia pianificando un lavoro approfondito sull'ereditarietà multipla (e di nuovo, ora potrebbe non essere il momento per quello), probabilmente non hai nemmeno bisogno di usare super (). Il solito metodo "IPlugin .__ init __ (self, ...)" per chiamare una superclasse conosciuta è la cosa più semplice da fare; super () non è sempre "il modo più nuovo e migliore di fare le cose" e ci sono cose che dovresti capire al riguardo prima di iniziare a caricarlo per usarlo.

Altri suggerimenti

A meno che tu non stia eseguendo una versione di Python precedente alla 2.2 (abbastanza improbabile), super () è sicuramente un funzione integrata (disponibile in tutti gli ambiti e senza importare nulla).

Potrebbe valere la pena di verificare la versione di Python (basta avviare il prompt interattivo digitando python dalla riga di comando).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top