2009-08-05 5 views
0

Dire que j'ai le code suivant:Comment obtenir une référence au module dans lequel quelque chose est implémenté depuis cette implémentation?

from foo.bar import Foo 
from foo.foo import Bar 

__all__ = ["Foo", "Bar"] 

def iterate_over_all(): 
    ... 

Comment puis-je mettre en œuvre le code dans la fonction iterate_over_all() qui peut obtenir dynamiquement des références à tout ce qui est référencé dans __all__ le module où la fonction est mise en œuvre? IE: en iterate_over_all() Je veux travailler avec foo.bar.Foo et foo.foo.Bar.

+0

Pouvez-vous clarifier un peu la question? Voulez-vous dire que vous voulez pouvoir passer de la chaîne "Foo" à l'objet Foo et ensuite au module qui contient Foo? – mikej

+0

Je ne comprends pas: Vous voulez une référence à quelque chose qui est dans __all__, par exemple. "Foo", alors vous voulez aller de "Foo" à Foo, c'est ça? Ou vous voulez obtenir de "Foo" à foo.bar ?! La partie * "... référencée dans __all__ le module où ..." * est plutôt difficile. – ThomasH

+0

Désolé les gars, clarification ajouté. – jkp

Répondre

2

Serait-ce faire?

def iterate_over_all(): 
    for name in __all__: 
     value = globals()[name] 
     yield value # or do whatever with it 
+0

Vous avez raison, * globals() * est en fait plus agréable que d'essayer d'obtenir * \ _ \ _ dict \ _ \ _ *, et pour les besoins de cette question, il semble avoir les mêmes clés avec les bonnes références. – ThomasH

0

eval est un sens. par exemple. eval("Foo") vous donnerait Foo. Cependant, vous pouvez également placer Foo et Bar directement dans votre liste, par exemple. __all__ = [Foo, Bar]

Cela dépend de l'origine du contenu de __all__ dans votre programme actuel.

+1

Salut Mike, oui cela fonctionnerait mais selon les docs il devrait s'agir de chaînes: "L'instruction import utilise la convention suivante: si le code __init__.py d'un paquet définit une liste nommée __all__, il est considéré comme la liste des noms de modules cela devrait être importé quand le paquet import * est rencontré. " (http://docs.python.org/tutorial/modules.html?highlight=__all__) – jkp

+0

Merci pour le lien. Est-ce que le fait de regarder les objets dans globals() fonctionnerait? par exemple. globals() ["Foo"] – mikej

+0

@mikej Oui, je le dirais, voyez la réponse de Martin. – ThomasH

0

Vous pouvez facilement index avec les chaînes de __all__ dans __dict__ de module:

__dict__["Foo"] == foo.bar.Foo # -> True 
+1

Thomas: bonne réponse, mais comment faire référence à la dictée de ce module? – jkp

+0

Ah, je pensais que * \ _ \ _ dict \ _ \ _ * serait disponible tout de suite ... Voici un moyen de l'obtenir: * sys.modules [globals() [\ _ \ _ name \ _ \ _]] . \ _ \ _ dict \ _ \ _ *. (Gee, j'aurais aimé qu'il y ait un * self * au niveau du module ...). – ThomasH

+0

Il est vraiment amusant que d'autres attributs de module soient disponibles gratuitement, comme * \ _ \ _ nom \ _ \ _ * et * \ _ \ _ fichier \ _ \ _ *, tandis que * \ _ \ _ dict \ _ \ _ * n'est pas disponible. – ThomasH

Questions connexes