Estoy escribiendo una aplicación. Sin interfaz gráfica de usuario sofisticada: s o algo, simplemente una aplicación de consola vieja y sencilla. Esta aplicación, vamos a llamarla Aplicación, necesita poder cargar complementos al inicio. Así que, naturalmente, he creado una clase para los plugins para heredar de:Importación dinámica de módulos seguida de creación de instancias de objetos con cierta clase base de dichos módulos
class PluginBase(object):
def on_load(self):
pass
def on_unload(self):
pass
def do_work(self, data):
pass
La idea es que en el arranque, la aplicación sería caminar por el directorio actual, incluyendo subdirectorios, en busca de módulos que contiene las clases que ellos mismos son subclases de PluginBase
.
Más código:
class PluginLoader(object):
def __init__(self, path, cls):
""" path=path to search (unused atm), cls=baseclass """
self.path=path
def search(self):
for root, dirs, files in os.walk('.'):
candidates = [fname for fname in files if fname.endswith('.py') \
and not fname.startswith('__')]
## this only works if the modules happen to be in the current working dir
## that is not important now, i'll fix that later
if candidates:
basename = os.path.split(os.getcwd())[1]
for c in candidates:
modname = os.path.splitext(c)[0]
modname = '{0}.{1}'.format(basename, modname)
__import__(mod)
module = sys.modules[mod]
Después de la última línea en search
me gustaría de alguna manera a) encontrar todas las clases en el módulo recién cargada, b) comprobar si una o más de esas clases son subclases de PluginBase
yc) (si b) crea una instancia de esas/esas clases y agrega a la lista de módulos cargados de la aplicación.
He intentado varias combinaciones de issubclass
y otros, seguidas por un período de intensa dir
: ing y una hora de google en pánico. Encontré un enfoque similar al mío here e intenté simplemente copiar y pegar eso, pero recibí un error al decir que Python no admite las importaciones por nombre de archivo, en ese momento perdí mi concentración y, como resultado, esta publicación fue escrito.
Estoy en mi ingenio final aquí, toda la ayuda apreciada.
funcionó casi perfectamente, gracias! Agregué 'y cls .__ name__! = Base .__ name__' para evitar que la clase base se agregue a la lista de subclases. – manneorama