Comment obtenir une référence à un module à l'intérieur du module lui-même?


159

Comment puis-je obtenir une référence à un module à partir de ce module? Aussi, comment puis-je obtenir une référence au package contenant ce module?


7
Je soupçonne que vous posez peut-être cette question parce que vous avez une variable dans la portée du module (par exemple, BLAH = 10 en dehors d'une fonction ou d'une classe), puis une variable de classe / fonction nommée BLAH et que vous souhaitez différencier. Une question valable ici est: est-ce nécessaire? Les règles de portée sont notoirement sujettes à des erreurs, en particulier de la part de «l'idiot» qui récupère votre code après vous (c'est-à-dire vous, 6 mois plus tard). Des trucs comme celui-ci sont rarement nécessaires; J'essaie de les éviter complètement car ils sont souvent déroutants et modifiés à tort par la suite.
Kevin

2
@ KevinJ.Rice "l'idiot" qui récupère votre code après vous (ie, vous, 6 mois plus tard) "a fait ma journée!
arctelix

8
Qui se soucie de savoir pourquoi il pose la question? Il existe de nombreuses raisons valables de le faire.
Christopher Barber

Doit être fermé. Trop utile.
mlvljr

Réponses:


212
import sys
current_module = sys.modules[__name__]

3
sauf que cela ne sera pas tout à fait correct si le module est rechargé; Je ne pense pas qu'il y ait un endroit où une référence est garantie d'être conservée, si c'était le cas, le rechargement ne fonctionnerait pas vraiment, non?
Dima Tisnek

14
Le rechargement réutilise le même objet module; aucun nouvel objet module n'est créé, il est donc toujours correct face au rechargement.
bukzor

18

Une autre technique, qui n'importe pas le module sys, et sans doute - dépend de votre goût - plus simple:

current_module = __import__(__name__)

Sachez qu'il n'y a pas d'importation. Python importe chaque module une seule fois.


Cela semble être une très bonne façon d'éviter d'importer sys. En plus d'être un peu contre-intuitif à lire, y a-t-il des inconvénients potentiels à cette approche?
JeremyDouglass

@JeremyDouglass. Pas que je sache. import est une fonction intégrée légitime, documentée (la seule fonction xx ). Vous pouvez le remplacer par le package 'importlib' (vous devrez l'importer). Peut-être que - ne m'est jamais arrivé - vous pourriez avoir un problème avec l'importation relative / absolue, si un module avec le même nom est disponible dans sys.path, auquel cas vous pouvez le résoudre avec l'argument 'level' de la fonction.
Uri

16

Si vous avez une classe dans ce module, la __module__propriété de la classe est le nom du module de la classe. Ainsi, vous pouvez accéder au module via sys.modules[klass.__module__]. Cela fonctionne également pour les fonctions.


4
En fait, il semble que (au moins) pour une fonction, la __module__propriété ne soit pas un module, mais une chaîne; ainsi a inspect.getabsfile(func.__module__)échoue avec " TypeError: 'os' n'est pas un module, une classe, une méthode, une fonction, une traceback, un cadre ou un objet de code "; tandis que inspect.getabsfile(sys.modules[o.__module__])semble passer.
sdaau

12

Vous pouvez obtenir le nom du module actuel en utilisant __name__

La référence du module se trouve dans le sys.modulesdictionnaire.

Voir la documentation Python


1

Vous pouvez le transmettre de l'extérieur:

mymod.init(mymod)

Pas idéal mais cela fonctionne pour mon cas d'utilisation actuel.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.