Frage

Ich schreibe ein Plugin-System für mein Programm und ich kann nicht über eine Sache bekommen:

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)

Nun ist die IPlugin sieht wie folgt aus:

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

Alle IPlugin Klassen arbeitet flawlessy von ihnen selbst, aber wenn sie von ThingLoader das Programm wird eine Ausnahme genannt:

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

Ich sah alle um, und ich einfach nicht wissen, was los ist.

War es hilfreich?

Lösung

‚super‘ ist ein builtin. Es sei denn, Sie aus dem Weg gehen builtins zu löschen, sollten Sie nicht immer „globale Namen‚super‘ist nicht definiert“ sehen.

Ich freue mich auf Ihre Benutzer Weblink , wo es einen Dump von IntrospectionHelper. Es ist sehr schwer, ohne die Vertiefung zu lesen, aber es sieht aus wie Sie 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]

Das ist das Original-Modul dict Sie dort sind zu ändern, nicht eine Informationskopie Sie sind über zurückzukehren! Löschen Sie diese Mitglieder aus einem Live-Modul und Sie können viel mehr als ‚super‘ erwarten zu brechen.

Es ist sehr schwer, den Überblick zu behalten, was das Modul tut, aber meine Reaktion ist es in es viel zu viel Magie. Das durchschnittliche Python-Programm sollte nie brauchen, um Mitglieder mit dem Importsystem, sys.path und Affe-Patchen __magic__ Modul Messing werden. Ein wenig Magie kann ein netter Trick sein, aber das ist äußerst fragil. Direkt an der Spitze von meinem Kopf von ihm gerade, könnte der Code durch Dinge gebrochen werden wie:

  • Namenskollisionen mit Top-Level-Module
  • jede Nutzung neuer Stil Klassen
  • Module nur als kompilierte Bytecode geliefert
  • zipimporter

Von den unglaublich Rund über Funktionen wie getClassDefinitions, extractModuleNames und isFromBase, sieht es für mich wie Sie immer noch ziemlich viel haben über die Grundlagen zu lernen, wie Python funktioniert. (Clues. Getattr, Modul .__ name__ und issubclass, jeweils)

In diesem Fall jetzt ist nicht die Zeit taucht in Import Magie zu sein! Es ist hart . Stattdessen Dinge tun, die normale Python Way. Es kann sein, ein wenig mehr Typisierung am Boden sagen eines Pakets 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 auf einige vertiefte Mehrfachvererbung Arbeit planen (und wieder kann jetzt nicht die Zeit dafür sein), brauchen Sie wahrscheinlich nicht einmal Super () zu verwenden. Die übliche „IPlugin .__ init __ (self, ...)“ Verfahren zur Herstellung eines bekannten Super Aufruf ist die einfache Sache zu tun; super () ist nicht immer „die neuere, bessere Art und Weise, Dinge zu tun“ und gibt es Dinge, die Sie sollten darüber verstehen , bevor Sie Laden gehen in es zu benutzen.

Andere Tipps

Wenn Sie eine Version von Python laufen früher als 2,2 (ziemlich unwahrscheinlich), ist auf jeden Fall ein super()

scroll top