2010-06-15 22 views
6

Parece que no puedo enumerar todas las clases derivadas utilizando el método __subclasses__(). Aquí está mi disposición de directorios:Python __subclasses __() sin enumerar las subclases

import.py 
backends 
     __init__.py 
    --digger 
      __init__.py 
      base.py 
      test.py 
     --plugins 
       plugina_plugin.py 

De import.py estoy llamando test.py. test.py itera a su vez sobre todos los archivos en el directorio plugins y los carga a todos. test.py se parece a esto:

import os 
import sys 
import re 

sys.path.append(os.path.join(os.path.abspath(os.path.dirname(os.path.abspath(__file__))))) 
sys.path.append(os.path.join(os.path.abspath(os.path.dirname(os.path.abspath(__file__))), 'plugins')) 

from base import BasePlugin 

class TestImport: 
    def __init__(self): 
     print 'heeeeello' 

     PLUGIN_DIRECTORY = os.path.join(os.path.abspath(os.path.dirname(os.path.abspath(__file__))), 'plugins') 

     for filename in os.listdir (PLUGIN_DIRECTORY): 
      # Ignore subfolders 
      if os.path.isdir (os.path.join(PLUGIN_DIRECTORY, filename)): 
       continue 
      else: 
       if re.match(r".*?_plugin\.py$", filename): 
        print ('Initialising plugin : ' + filename) 
        __import__(re.sub(r".py", r"", filename)) 

     print ('Plugin system initialized') 
     print BasePlugin.__subclasses__() 

El problema nosotros que el método __subclasses__() no muestra clases derivadas. Todos los complementos en el directorio plugins derivan de una clase base en el archivo base.py.

base.py se parece a esto:

class BasePlugin(object): 
    """ 
    Base 
    """ 
    def __init__(self): 
     pass 

plugina_plugin.py se parece a esto:

de la base BasePlugin importación

class PluginA(BasePlugin): 
    """ 
    Plugin A 
    """ 
    def __init__(self): 
     pass 

Podría alguien ayudarme con esto? ¿Qué estoy haciendo mal? Me he metido en mis cerebros por esto, pero no puedo entenderlo

Gracias.

+0

¿Ves el mensaje 'Initialising plugin: plugina_plugin'? – unutbu

+0

Sí. Aparece. Parece que la clase incluso se importa, pero el método '__subclasses__' no lo incluye por algún motivo. –

+0

No he podido reproducir el problema. 'print BasePlugin .__ subclasses__()' produce '[]'.Tal vez si copia la estructura del directorio y sigue reduciendo el código a su forma más simple posible (con cada prueba de cambio si el problema persiste), en una etapa intermedia encontrará una pista sobre el origen del problema. Por ejemplo, deshágase de todos los códigos extraños en test.py, simplifique la estructura del directorio, deshágase de import.py, etc ... – unutbu

Respuesta

4

No hubo otros archivos base.py. Estoy en un WinXP (SP2) con Python 2.6. Agregué otra clase a mi archivo test.py llamado PluginB que usó BasePlugin como clase base. Cuando lo hice

print PluginA.__mro__ 
    print PluginB.__mro__ 

llegué:

(<class 'plugina_plugin.PluginA'>, <class 'base.BasePlugin'>, <type 'object'>) 
(<class 'backends.digger.test.PluginB'>, <class 'backends.digger.base.BasePlugin'>, <type 'object'>) 

Como se puede ver, los dos están utilizando el mismo plugin de base, pero los nombres calificados son diferentes. Esto fue debido a que en plugina_plugin.py me importaba BasePlugin así:

from base import BasePlugin 

En lugar de:

from backends.digger.base import BasePlugin 

La fijación de este arreglaron.

+0

¡Gracias por investigar este problema! ¿Quién hubiera pensado que un objeto con dos nombres diferentes calificados tiene dos alias independientes? – advait

0

Quizás los complementos encuentren otro base.py oculto en algún lugar (el directorio del complemento, por ejemplo).
Ejecutar con python -v para ver si dos diferentes base.py están siendo importados

También puede mirar en PluginA.__mro__ y confirmar que el BasePlugin allí es la correcta

Cuestiones relacionadas