2011-02-18 1 views
0

J'ai un dossier ouvert sur mon ordinateur,importation automatique pour tous les sous-modules dans un dossier, puis appeler des fonctions même nom - runtime python inspecter liées

OpenFunctions\ 
    ____Template.py 
    function1.py 
    function2.py 
    ...... 
    functionx.py 

Ce dossier est objectif expérimental pour étendre la capacité de l'application entière peut faire. Donc, pensons simplement que c'est une tentative rapide et sèche, aucune considération de sécurité dans ce cas. Mon but est, si je laisse tomber un functionx.py suivant le ____Template.py, l'application peut savoir les nouvelles fonctions est disponible et invoquera les fonctions définies dans ce nouveau fichier joint dans quelque chose - quelque chose comme le système de plugin, mais devrait être un Un peu différent.

Donc, j'ai écrit un ____inspect.py peut laisser l'application avoir une capacité de savoir ce qui a été entré.

Voici le

____inspect.py 

def get_this_file_defined_functions(name_filter = "__"): 
    import inspect, sys 
    f = inspect.getmembers(sys.modules[__name__], inspect.isfunction) 
    return [x for x in f if not x[0].startswith(name_filter)] 

def get_this_module_sub_modules(name_filter = "__"): 
    import os.path, pkgutil 
    pkgpath = os.path.dirname(__file__) 
    m = [name for _, name, _ in pkgutil.iter_modules([pkgpath])] 
    return [x for x in m if not x[0].startswith(name_filter)] 

def import_sub_modules_under_me(auto_exec_function = "auto_exec"): 
    m = get_this_module_sub_modules() 
    for i in m: # need try except later 
     exec "global %s; import %s" % (i, i) 
     #this will auto invoke __init__.py if sub modules folder is included 
    for i in m: 
     try: 
      eval(i).eval(auto_exec_function)() 
     except AttributeError: 
      print "module %s has no function %s", % (i, auto_exec_function) 
     else: 
      print "error on execute %s in module %s", % (auto_exec_function, i) 

def execute_all_homonymy_functions(exec_function = "exec"): 
    m = get_this_module_sub_modules() 
    for i in m: 
     #I need here for test if the module has been imported 
     eval(i).eval(exec_function)() 

Voici le

____Template.py 

def __you_can_not_see_me(): pass # because filtered by str.startswith() 
def auto_exec(): pass    # this will be auto executed 
def you_can_get_me(): pass 
def you_can_get_me1(): pass 
def you_can_get_me2(): pass 

basée sur idée ci-dessus, je tiens également à étendre la structure au-dessous

main.py 
____inspect.py 
OpenFunctions\ 
    __init__.py 
    ____Template.py 
    function1.py 
    function2.py 
    ...... 
    functionx.py 
    module_aa 
     \__init__.py 
      aa.py 
      aa1.py 

Voici le main.py alors que le __init__.py peut ressembler à

import ____inspect 
____inspect.import_sub_modules_under_me() 
____inspect.execute_all_homonymy_functions("what_ever_i_want") 

Questions:

  1. Au-dessus __init__ code ne fonctionne pas, parce que le sys.modules[__name__] est-____inspect lorsque vous invoquez mais pas le OpenFunctions ou module_aa je veux, est-il un moyen d'éviter passer le sys.modules[__name__] au import_sub_modules_under_me() sur le main.py ou le __init__.py? Je suppose que execute_all_homonymy_functions() exécutera la même fonction de nom dans le dossier, quel que soit son existence dans un sous-module ou dans un seul fichier, mais je souhaite invoquer tout et la dernière version au cas où le nouveau module ajouté ou le source a été modifié runtime. Ensuite, je veux utiliser le code import aa, reload(aa) mais peut être considéré comme le mauvais sur le lien ci-dessous, des suggestions? La question que je marqué I need here for test if the module has been imported dans _ _inspect.py

    [http://stackoverflow.com/questions/5027352/how-to-test-if-one-python-module-has-been-imported] Je veux aussi connaître le type de retour d'une fonction dans un fichier avant de l'appeler, il a été suggéré d'attacher un décor sur chaque fonction. Donc, mon plan est:

\ n

____decorate.py 

def attrs(**kwds): 
    def decorate(f): 
     for k in kwds: 
      setattr(f, k, kwds[k]) 
     return f 
    return decorate 

functionx.py 
import ../____decorate.py 

@attrs(argument_types=(int, int,),returns=int) 
def __you_can_not_see_me(): pass 

@attrs(argument_types=(int, int,),returns=int) 
def auto_exec(): pass    # I will be auto executed 

@attrs(argument_types=(int, int,),returns=int) 
def you_can_get_me(): pass 

@attrs(argument_types=(int, int,),returns=int) 
def you_can_get_me1(): pass 

@attrs(argument_types=(int, int,),returns=int) 
def you_can_get_me2(): pass 

est-il fonctionne bien pour inspecter le cas? Ou y a-t-il une meilleure solution?

Le dernier: le code ci-dessous

exec "global %s; import %s" % (i, i) 
eval(i).eval(auto_exec_function)() 

semble laid, une alternative pour les deux lignes ci-dessus?

Merci pour votre aide.

RBP, KC

Répondre

2

Pour répondre à votre dernière question: importer dynamiquement des modules dans les versions récentes de Python, utilisez importlib.import_module(), c'est ce qu'il est pour. Si vous utilisez une ancienne version de Python, vous devez utiliser __import__ à la place (mais vérifiez les particularités de cette approche directe dans les documents - il y a une raison pour laquelle la fonction import_module() a été ajoutée en remplacement).

Pour répondre à votre première question: il n'existe pas de moyen officiellement portable de récupérer des informations sur l'environnement global de la fonction appelante. La réponse la plus correcte consiste donc simplement à passer __name__ en argument là où c'est nécessaire.

Recharger en Python est toujours un peu dangereux, car tout ne fonctionne pas correctement lors du rechargement (même de nombreux modules de bibliothèque standard échoueront si vous les rechargez, ou un module auquel ils font référence).

Je suggère vraiment passer du temps à explorer les réponses à cette question existante sur les architectures de plugins en Python: Building a minimal plugin architecture in Python

+0

merci pour la réponse, je l'ai lu module plug-in serval avant, mais je trouve un problème commun pour moi les système de plugin peut aimer une classe - vous devez définir des plugins suivant le modèle strict. pour la plupart des systèmes c'est ok, mais pour moi de finir ces travaux sales, ça ne vaut pas la peine pour moi d'écrire ces codes spéciaux. merci encore pour votre suggestion – user478514

+0

et sale signifie simplement one-off ici, désolé pour mon anglais. – user478514

Questions connexes