2009-03-04 12 views
2

Ich bin ein Plugin-System für mein Programm zu schreiben, und ich kann nicht in der Vergangenheit eine Sache bekommen:Problem mit Super (Python 2.5.2)

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 

Der Test Plugin sieht wie folgt aus:

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) 

Jetzt sieht die IPlugin wie folgt aus:

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

den IPlugin Klassen arbeitet flawlessy Alle von ihnen selbst, aber wenn sie von ThingLoader das prog genannt ram bekommt eine ausnahme:

Ich schaute überall und ich weiß einfach nicht, was vor sich geht.

+0

Nachdem ich die akzeptierte Antwort gelesen habe, bin ich versucht, die Frage als unvollständig und irreführend abzustempeln. –

Antwort

20

'Super' ist ein Builttin. Sofern Sie sich nicht darum gekümmert haben, Built-Ins zu löschen, sollten Sie niemals sehen, dass der globale Name 'super' nicht definiert ist.

Ich schaue auf Ihre user web link, wo es einen Dump von IntrospectionHelper gibt. Es ist sehr schwer, ohne die Vertiefung zu lesen, aber es sieht aus wie Sie, dass genau das tun können:

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

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

, dass das ursprüngliche Modul ist dict Sie dort sind zu ändern, nicht eine Informationskopie Sie zurück sind! Löschen Sie diese Mitglieder aus einem Live-Modul und Sie können erwarten, dass viel mehr als "Super" bricht.

Es ist sehr schwer zu verfolgen, was das Modul macht, aber meine Reaktion ist, dass es viel zu viel Magie darin ist. Das durchschnittliche Python-Programm sollte sich nie mit den Import-System-, sys.path- und affe-patchen __magic__-Modul-Mitgliedern herumschlagen müssen. Ein bisschen Magie kann ein netter Trick sein, aber das ist extrem fragil.

  • Namenskollisionen mit Top-Level-Module
  • jeder Einsatz neuen Stil Klassen
  • Module nur geliefert, wie: Direkt an der Spitze von meinem Kopf von ihm gerade, könnte der Code durch Dinge wie gebrochen wird kompilierten Bytecode
  • zipimporter

von den unglaublich Rund über Funktionen wie getClassDefinitions, extractModuleNames und isFromBase, es mir sieht aus wie Sie immer noch ziemlich viel haben über die Grundlagen von h lernen Python funktioniert. (Hinweise: getattr, modul .__ name__ und issubclass, jeweils.)

In diesem Fall ist jetzt nicht die Zeit, in Import Magie tauchen! Es ist hart. Machen Sie stattdessen Dinge wie die normale Python-Methode. Es kann ein wenig mehr Typisierung sein an der Unterseite des ein Pakets zu sagen mypackage/__ init__.py:

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

aber es wird funktionieren und überall, ohne auf ein Nest von komplexer, fragiler Magie unter Berufung verstanden werden.

Übrigens, es sei denn, Sie planen eine gründliche Mehrfachvererbung (und vielleicht ist es auch nicht die Zeit dafür), müssen Sie wahrscheinlich nicht einmal super() verwenden. Das übliche "IPlugin .__ init __ (self, ...) "Die Methode, eine bekannte Oberklasse zu nennen, ist einfach. super() ist nicht immer "der neuere, bessere Weg, Dinge zu tun" und there are things you should understand about it, bevor Sie in die Nutzung gehen.

+2

+1 für die tatsächliche Verfolgung eines Links auf der Benutzerseite, um eine Kopie des Codes zu finden und anschließend zu debuggen. Dies muss eine der am gründlichsten erforschten Antworten sein. – DNS

+0

Er sollte einen Preis daraus bekommen! – Diones

+0

Es muss sehr angenehm gewesen sein, diese Antwort zu schreiben. +1 – nosklo

0

Sofern Sie nicht eine Version von Python früher als 2.2 (ziemlich unwahrscheinlich) ausführen, ist super() definitiv eine built-in function (in jedem Bereich verfügbar und ohne etwas zu importieren).

Vielleicht lohnt es sich, Ihre Version von Python zu überprüfen (starten Sie einfach die interaktive Eingabeaufforderung, indem Sie in der Befehlszeile python eingeben).