Pergunta

Eu estou escrevendo um sistema de plugins para o meu programa e eu não posso passar por uma coisa:

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

O teste do plugin parecido com este:

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)

Agora, o IPlugin parece com isso:

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

Todas as classes IPlugin funciona flawlessy por eles mesmos, mas quando chamado por ThingLoader o programa recebe uma exceção:

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

Eu olhei ao redor e eu simplesmente não sei o que está acontecendo.

Foi útil?

Solução

‘super’ é um builtin. A menos que você saiu do seu caminho para builtins de exclusão, você não deve nunca ver “nome global 'super' não está definido”.

Eu estou olhando para o seu user link web onde há um despejo de IntrospectionHelper. É muito difícil de ler sem o recuo, mas parece que você pode estar fazendo exatamente isso:

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

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

Isso é o módulo original dict você está mudando lá, não uma cópia de informação que você está prestes a troca! Excluir esses membros de um módulo ao vivo e você pode esperar muito mais do que ‘super’ para quebrar.

É muito difícil manter o controle do que esse módulo está fazendo, mas minha reação é que há demasiada magia. O programa de média Python nunca precisará ser brincando com o sistema de importação, sys.path e-remendar macaco __magic__ membros do módulo. Um pouco de magia pode ser um truque, mas isso é extremamente frágil. Apenas fora do topo da minha cabeça de navegar ele, o código poderia ser quebrado por coisas como:

  • confrontos com nome módulos de nível superior
  • qualquer uso de classes de estilo novo
  • módulos fornecidas apenas como bytecode compilado
  • zipimporter

Do incrivelmente rotunda funções como getClassDefinitions, extractModuleNames e isFromBase, parece-me que você ainda tem um pouco para aprender sobre os conceitos básicos de como Python funciona. (Pistas:. GetAttr, módulo .__ name__ e issubclass, respectivamente)

Neste caso agora é não o tempo para estar mergulhando em magia de importação! É duro . Em vez disso, fazer as coisas O normal Python caminho. Pode ser um pouco mais digitando a dizer na parte inferior de um pacote é mypackage / __ o init __ py:.

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

mas ele vai trabalhar e ser compreendido em todos os lugares, sem depender de um ninho de complexo mágica, frágil.

A propósito, a menos que você está pensando em alguns em profundidade o trabalho de herança múltipla (e novamente, agora pode não ser o momento para isso), você provavelmente não precisa nem usar super (). O usual “IPlugin .__ o init __ (self, ...)” método de chamar uma superclasse conhecida é a coisa simples de fazer; super () nem sempre é “a melhor maneira nova, de fazer as coisas” e há coisas que você deve entender sobre isso antes de ir carregar em usá-lo.

Outras dicas

A menos que você estiver executando uma versão do Python mais cedo do que 2.2 (muito improvável), super() é definitivamente um built-in função (disponível em todos os âmbitos, e sem importar nada).

Pode valer a pena verificar a sua versão do Python (simplesmente iniciar o prompt interativo, python digitando na linha de comando).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top