Come trovare tutti i moduli figlio in Python?
-
06-09-2019 - |
Domanda
Mentre è abbastanza banale in Python per importare un modulo di "bambino" in un altro modulo ed elencare i suoi attributi, diventa un po 'più difficile quando si desidera importare tutti moduli bambino.
Sto costruendo una libreria di strumenti per un'applicazione 3D esistente. Ogni strumento ha le proprie menu voce di menu e sub. Mi piacerebbe lo strumento per essere responsabile della creazione dei propri menu come molti di loro cambiano in base al contesto e modelli. Vorrei che il mio modulo di base per essere in grado di trovare tutti i moduli dei bambini e verificare la presenza di una funzione create_menu()
e chiamarla se lo trova.
Qual è il modo più semplice per scoprire tutti i moduli bambino?
Soluzione
Altri suggerimenti
Credo che il modo migliore per fare questo genere di cose plug-in sta usando entry_points
e il API per loro interrogazione .
Quando ero una specie e la programmazione solo all'inizio in Python che ho scritto questo per il mio bot IRC modulare:
# Load plugins
_plugins = []
def ifName(name):
try:
return re.match('([^_.].+)\.[^.]+', a).group(1)
except:
return None
def isValidPlugin(obj):
from common.base import PluginBase
try:
if obj.__base__ == PluginBase:
return True
else:
return False
except:
return False
plugin_names = set(ifilter(lambda a: a!=None, [ifName(a) for a in os.listdir(os.path.join(os.getcwd(), 'plugins'))]))
for plugin_name in plugin_names:
try:
plugin = __import__('plugins.'+plugin_name, fromlist=['plugins'])
valid_plugins = filter(lambda a: isValidPlugin(a), [plugin.__getattribute__(a) for a in dir(plugin)])
_plugins.extend(valid_plugins)
except Exception, e:
logger.exception('Error loading plugin %s', plugin_name)
# Run plugins
_plugins = [klass() for klass in _plugins]
Non è sicuro o modo "giusto", ma forse ci sarà utile comunque. E ' molto il vecchio codice quindi per favore non mi ha battuto.
La soluzione di cui sopra che attraversa il filesystem per la ricerca di moduli è ok fintanto che si sceglie di implementare tutti i plugin come modulo base filesystem.
Un modo più flessibile sarebbe una lista di plugin di esplicito nel vostro modulo principale, e hanno tutti i plugin (se un modulo creato da lima, in modo dinamico, o anche un'istanza di una classe) si aggiunge a quella lista in modo esplicito. Forse attraverso una funzione registerPlugin.
Ricorda:. "Esplicito è meglio che implicita" fa parte di Lo Zen di Python
Si può provare glob
bing directory:
import os
import glob
modules = glob.glob(os.path.join('/some/path/to/modules', '*.py'))
Allora si può provare la loro importazione:
checked_modules
for module in modules:
try:
__import__(module, globals(), locals()) # returns module object
except ImportError:
pass
else:
checked_modules.append(module)