¿Cómo obtener una referencia a un módulo dentro del propio módulo?

159

¿Cómo puedo obtener una referencia a un módulo desde ese módulo? Además, ¿cómo puedo obtener una referencia al paquete que contiene ese módulo?

Ram Rachum
fuente
77
Sospecho que podría estar haciendo esta pregunta porque tiene una variable en el alcance del módulo (por ejemplo, BLAH = 10 fuera de una función o clase), luego una variable de clase / función llamada BLAH, y desea diferenciar. Una pregunta válida aquí es: ¿Es esto necesario? Las reglas de alcance son notoriamente propensas a equivocarse, especialmente por el 'idiota' que recoge su código después de usted (es decir, usted, 6 meses después). Trucos como este rara vez son necesarios; Intento evitarlos por completo porque a menudo son confusos y modificados erróneamente más tarde.
Kevin J. Rice
2
@ KevinJ.Rice "¡el 'idiota' que recoge tu código después de ti (es decir, tú, 6 meses después)" me alegró el día!
arctelix
8
¿A quién le importa por qué hace la pregunta? Hay muchas razones válidas para hacer esto.
Christopher Barber
Necesita ser cerrado. Demasiado útil
mlvljr

Respuestas:

212
import sys
current_module = sys.modules[__name__]
truppo
fuente
3
excepto que esto no será del todo correcto si se recarga el módulo; No creo que haya un lugar donde se garantice que se mantenga una referencia, si la hubiera, la recarga realmente no funcionaría, ¿verdad?
Dima Tisnek
14
La recarga reutiliza el mismo objeto de módulo; no se crea ningún nuevo objeto de módulo, por lo que sigue siendo correcto antes de volver a cargarlo.
bukzor
18

Una técnica más, que no importa el módulo sys, y podría decirse, depende de su gusto, más simple:

current_module = __import__(__name__)

Tenga en cuenta que no hay importación. Python importa cada módulo solo una vez.

Uri
fuente
Esto parece una muy buena manera de evitar importar sys. Además de ser un poco contradictorio para leer, ¿hay algún inconveniente potencial en este enfoque?
JeremyDouglass
@JeremyDouglass. No que yo supiese. import es una función legítima, documentada e integrada (la única función xx ). Puede reemplazarlo con el paquete 'importlib' (deberá importarlo). Tal vez, nunca me sucedió, podría tener un problema con la importación relativa / absoluta, si un módulo con el mismo nombre está disponible en sys.path, en cuyo caso puede resolverlo con el argumento 'nivel' de la función.
Uri
16

Si tiene una clase en ese módulo, la __module__propiedad de la clase es el nombre del módulo de la clase. Por lo tanto, puede acceder al módulo a través de sys.modules[klass.__module__]. Esto también funciona para funciones.

Miguel
fuente
44
En realidad, parece que (al menos) para una función, la __module__propiedad no es un módulo, sino una cadena; por lo tanto, un inspect.getabsfile(func.__module__)error con " TypeError: 'os' no es un módulo, clase, método, función, rastreo, marco u objeto de código "; mientras inspect.getabsfile(sys.modules[o.__module__])parece pasar.
sdaau
12

Puede obtener el nombre del módulo actual usando __name__

La referencia del módulo se puede encontrar en el sys.modulesdiccionario.

Ver la documentación de Python

pkit
fuente
1

Puede pasarlo desde afuera:

mymod.init(mymod)

No es ideal, pero funciona para mi caso de uso actual.

Sam Watkins
fuente