imp
— Acceda a import internamente¶
Código fuente: Lib/imp.py
Este módulo proporciona una interfaz a los mecanismos utilizados para implementar la sentencia import
. Define las siguientes constantes y funciones:
-
imp.
get_magic
()¶ Retorna el valor de la cadena de caracteres mágica que se utiliza para reconocer archivos de código compilados por bytes (archivos
.pyc
). (Este valor puede ser diferente para cada versión de Python).Obsoleto desde la versión 3.4: Utilice
importlib.util.MAGIC_NUMBER
en su lugar.
-
imp.
get_suffixes
()¶ Retorna una lista de tuplas de 3 elementos, cada una de las cuales describe un tipo particular de módulo. Cada triple tiene la forma
(suffix, mode, type)
, donde suffix es una cadena de caracteres que se agregará al nombre del módulo para formar el nombre de archivo a buscar, mode es la cadena de caracteres de modo para pasar a la función incorporadaopen()
para abrir el archivo (esto puede ser'r'
para archivos de texto o'rb'
para archivos binarios), y type es el tipo de archivo, que tiene uno de los valoresPY_SOURCE
,PY_COMPILED
, oC_EXTENSION
, que se describen a continuación.Obsoleto desde la versión 3.3: Utilice las constantes definidas en
importlib.machinery
en su lugar.
-
imp.
find_module
(name[, path])¶ Intente encontrar el módulo name. Si se omite path o
None
, se busca la lista de nombres de directorio dados porsys.path
, pero primero se buscan algunos lugares especiales: la función intenta encontrar un módulo integrado con el nombre dado (C_BUILTIN
), a continuación, un módulo congelado (PY_FROZEN
), y en algunos sistemas algunos otros lugares se buscan también (en Windows, se ve en el registro que puede apuntar a un archivo específico).De lo contrario, path debe ser una lista de nombres de directorio; cada directorio se busca archivos con cualquiera de los sufijos retornados por
get_suffixes()
arriba. Los nombres no válidos de la lista se omiten silenciosamente (pero todos los elementos de lista deben ser cadenas).Si la búsqueda se realiza correctamente, el valor retornado es una tupla de 3 elementos
(file, pathname, description)
:file es un abierto file object posicionado al principio, pathname es el nombre de ruta del archivo encontrado, y description es una tupla de 3 elementos tal como se encuentra en la lista retornada por
get_suffixes()
que describe el tipo de módulo encontrado.Si el módulo no vive en un archivo, el archivo file retornado es
None
, pathname es la cadena vacía y la tupla description contiene cadenas vacías para su sufijo y modo; el tipo de módulo se indica como se indica entre paréntesis arriba. Si la búsqueda no se realiza correctamente, se provocaImportError
. Otras excepciones indican problemas con los argumentos o el entorno.Si el módulo es un paquete, file es
None
, pathname es la ruta de acceso del paquete y el último elemento de la tupla description esPKG_DIRECTORY
.Esta función no controla los nombres de módulo jerárquico (nombres que contienen puntos). Para encontrar P.M, es decir, submódulo M del paquete P, use
find_module()
yload_module()
para buscar y cargar el paquete P, y luego usefind_module()
con el argumento path establecido enP.__path__
. Cuando P tenga un nombre punteado, aplique esta receta de forma recursiva.Obsoleto desde la versión 3.3: Utilice
importlib.util.find_spec()
en su lugar a menos que se requiera compatibilidad con Python 3.3, en cuyo caso useimportlib.find_loader()
. Para ver el uso del caso anterior, consulte la sección Ejemplos de la documentaciónimportlib
.
-
imp.
load_module
(name, file, pathname, description)¶ Cargue un módulo que fue encontrado anteriormente por
find_module()
(o por una búsqueda realizada de otro modo que produce resultados compatibles). Esta función hace más que importar el módulo: si el módulo ya estaba importado, se recargará el módulo! El argumento name indica el nombre completo del módulo (incluido el nombre del paquete, si se trata de un submódulo de un paquete). El argumento file es un archivo abierto y pathname es el nombre de archivo correspondiente; pueden serNone
y''
, respectivamente, cuando el módulo es un paquete o no se carga desde un archivo. El argumento description es una tupla, como sería retornada porget_suffixes()
, que describe qué tipo de módulo se debe cargar.Si la carga se realiza correctamente, el valor retornado es el objeto modulo; de lo contrario, se produce una excepción (normalmente
ImportError
).Importante: el autor de la llamada es responsable de cerrar el argumento file, si no era
None
, incluso cuando se genera una excepción. Esto se hace mejor usando una declaracióntry
…finally
.Obsoleto desde la versión 3.3: Si se utiliza anteriormente junto con
imp.find_module()
considere usarimportlib.import_module()
, de lo contrario utilice el cargador retornado por el reemplazo que eligió paraimp.find_module()
. Si llamó aimp.load_module()
y funciones relacionadas directamente con argumentos de ruta de archivo, utilice una combinación deimportlib.util.spec_from_file_location()
yimportlib.util.module_from_spec()
. Consulte la sección Ejemplos de la documentaciónimportlib
para obtener más información sobre los distintos enfoques.
-
imp.
new_module
(name)¶ Retorna un nuevo objeto de módulo vacío denominado name. Este objeto es not insertado en
sys.modules
.Obsoleto desde la versión 3.4: Utilice
importlib.util.module_from_spec()
en su lugar.
-
imp.
reload
(module)¶ Vuelva a cargar un módulo importado anteriormente. El argumento debe ser un objeto module, por lo que debe haberse importado correctamente antes. Esto es útil si ha editado el archivo de origen del módulo utilizando un editor externo y desea probar la nueva versión sin salir del intérprete de Python. El valor retornado es el objeto module (el mismo que el argumento module).
Cuando se ejecuta
reload(module)
:El código de los módulos de Python se vuelve a compilar y se vuelve a ejecutar el código de nivel de módulo, definiendo un nuevo conjunto de objetos que están enlazados a nombres en el diccionario del módulo. La función
init
de los módulos de extensión no se llama una segunda vez.Al igual que con todos los demás objetos de Python, los objetos antiguos solo se recuperan después de que sus recuentos de referencia caigan a cero.
Los nombres del espacio de nombres del módulo se actualizan para que apunten a cualquier objeto nuevo o modificado.
Otras referencias a los objetos antiguos (como nombres externos al módulo) no se rebotan para hacer referencia a los nuevos objetos y deben actualizarse en cada espacio de nombres donde se producen si se desea.
Hay una serie de otras advertencias:
Cuando se vuelve a cargar un módulo, se conserva su diccionario (que contiene las variables globales del módulo). Las redefiniciones de nombres invalidarán las definiciones antiguas, por lo que esto generalmente no es un problema. Si la nueva versión de un módulo no define un nombre previamente definido, la definición anterior permanece. Esta característica se puede utilizar en beneficio del módulo si mantiene una tabla global o caché de objetos — con una instrucción
try
puede probar la presencia de la tabla y omitir su inicialización si se desea:try: cache except NameError: cache = {}
Es legal, aunque generalmente no es muy útil para recargar módulos incorporados o cargados dinámicamente, excepto para
sys
,__main__
ybuiltins
. En muchos casos, sin embargo, los módulos de extensión no están diseñados para inicializarse más de una vez y pueden fallar de forma arbitraria cuando se vuelven a cargar.Si un módulo importa objetos de otro módulo utilizando
from
…import
…, llamando areload()
para el otro módulo no redefine los objetos importados de él — de una manera alrededor de esto es volver a ejecutar la sentenciafrom
, otra es usarimport
y nombres calificados (module.*name*) en su lugar.Si un módulo crea instancias de una clase, volver a cargar el módulo que define la clase no afecta a las definiciones de método de las instancias — siguen utilizando la definición de clase antigua. Lo mismo es cierto para las clases derivadas.
Distinto en la versión 3.3: Se basa en que tanto
__name__
como__loader__
que se definen en el módulo que se está recargando en lugar de simplemente__name__
.Obsoleto desde la versión 3.4: Utilice
importlib.reload()
en su lugar.
Las siguientes funciones son comodidades para controlar las rutas de acceso de archivo PEP 3147 compiladas en bytes.
Nuevo en la versión 3.2.
-
imp.
cache_from_source
(path, debug_override=None)¶ Retorna la ruta de acceso PEP 3147 al archivo compilado por bytes asociado con la ruta path de origen. Por ejemplo, si path es
/foo/bar/baz.py
el valor retornado sería/foo/bar/__pycache__/baz.cpython-32.pyc
para Python 3.2. La cadenacpython-32
proviene de la etiqueta mágica actual (consulteget_tag()
; sisys.implementation.cache_tag
no está definida entoncesNotImplementedError
se generará). Al pasarTrue
oFalse
para debug_override puede reemplazar el valor del sistema para__debug__
, lo que da lugar a un código de bytes optimizado.ruta no necesita existir.
Distinto en la versión 3.3: Lanza
NotImplementedError
cuando no se definesys.implementation.cache_tag
.Obsoleto desde la versión 3.4: Utilice
importlib.util.source_from_cache()
en su lugar.Distinto en la versión 3.5: El parámetro debug_override ya no crea un archivo
.pyo
.
-
imp.
source_from_cache
(path)¶ Dada la ruta path a un nombre de archivo PEP 3147, retorne la ruta de acceso del archivo de código fuente asociada. Por ejemplo, si path es
/foo/bar/__pycache__/baz.cpython-32.pyc
la ruta retornada sería/foo/bar/baz.py
. path no necesita existir, sin embargo, si no se ajusta al formato PEP 3147, se genera unValueError
. Sisys.implementation.cache_tag
no está definido, se generaNotImplementedError
.Distinto en la versión 3.3: Provoca
NotImplementedError
cuando no se definesys.implementation.cache_tag
.Obsoleto desde la versión 3.4: Utilice
importlib.util.source_from_cache()
en su lugar.
-
imp.
get_tag
()¶ Retorna la cadena de etiqueta mágica PEP 3147 que coincida con esta versión del número mágico de Python, como lo retorna
get_magic()
.Obsoleto desde la versión 3.4: Utilice
sys.implementation.cache_tag
directamente a partir de Python 3.3.
Las siguientes funciones ayudan a interactuar con el mecanismo de bloqueo interno del sistema de importación. La semántica de bloqueo de las importaciones es un detalle de implementación que puede variar de una versión a una. Sin embargo, Python garantiza que las importaciones circulares funcionen sin interbloqueos.
-
imp.
lock_held
()¶ Retorna
True
si el bloqueo de importación global está actualmente retenido, de lo contrario,False
. En plataformas sin hilos, siempre retornaFalse
.En plataformas con subprocesos, un subproceso que ejecuta una importación primero contiene un bloqueo de importación global y, a continuación, configura un bloqueo por módulo para el resto de la importación. Esto impide que otros subprocesos importen el mismo módulo hasta que se complete la importación original, lo que impide que otros subprocesos vean objetos de módulo incompletos construidos por el subproceso original. Se hace una excepción para las importaciones circulares, que por construcción tienen que exponer un objeto de módulo incompleto en algún momento.
Distinto en la versión 3.3: El esquema de bloqueo ha cambiado a bloqueos por módulo en su mayor parte. Se mantiene un bloqueo de importación global para algunas tareas críticas, como la inicialización de los bloqueos por módulo.
Obsoleto desde la versión 3.4.
-
imp.
acquire_lock
()¶ Adquiera el bloqueo de importación global del intérprete para el subproceso actual. Este bloqueo debe ser utilizado por los ganchos de importación para garantizar la seguridad de subprocesos al importar módulos.
Una vez que un subproceso ha adquirido el bloqueo de importación, el mismo subproceso puede adquirirlo de nuevo sin bloquear; el subproceso debe liberarlo una vez por cada vez que lo ha adquirido.
En plataformas sin subprocesos, esta función no hace nada.
Distinto en la versión 3.3: El esquema de bloqueo ha cambiado a bloqueos por módulo en su mayor parte. Se mantiene un bloqueo de importación global para algunas tareas críticas, como la inicialización de los bloqueos por módulo.
Obsoleto desde la versión 3.4.
-
imp.
release_lock
()¶ Suelte el bloqueo de importación global del intérprete. En plataformas sin subprocesos, esta función no hace nada.
Distinto en la versión 3.3: El esquema de bloqueo ha cambiado a bloqueos por módulo en su mayor parte. Se mantiene un bloqueo de importación global para algunas tareas críticas, como la inicialización de los bloqueos por módulo.
Obsoleto desde la versión 3.4.
Las siguientes constantes con valores enteros, definidas en este módulo, se utilizan para indicar el resultado de búsqueda de find_module()
.
-
imp.
PY_SOURCE
¶ El módulo se encontró como un archivo de origen.
Obsoleto desde la versión 3.3.
-
imp.
PY_COMPILED
¶ El módulo se encontró como un archivo de objeto de código compilado.
Obsoleto desde la versión 3.3.
-
imp.
C_EXTENSION
¶ El módulo se encontró como biblioteca compartida cargable dinámicamente.
Obsoleto desde la versión 3.3.
-
imp.
PKG_DIRECTORY
¶ El módulo se encontró como un directorio de paquetes.
Obsoleto desde la versión 3.3.
-
imp.
C_BUILTIN
¶ El módulo fue encontrado como un módulo incorporado.
Obsoleto desde la versión 3.3.
-
imp.
PY_FROZEN
¶ El módulo fue encontrado como un módulo congelado.
Obsoleto desde la versión 3.3.
-
class
imp.
NullImporter
(path_string)¶ El tipo
NullImporter
es un enlace de importación PEP 302 que controla cadenas de ruta de acceso que no son de directorio al no encontrar ningún módulo. Llamar a este tipo con un directorio existente o una cadena vacía generaImportError
. De lo contrario, se retorna una instanciaNullImporter
.Las instancias solo tienen un método:
-
find_module
(fullname[, path])¶ Este método siempre retorna
None
, lo que indica que no se pudo encontrar el módulo solicitado.
Distinto en la versión 3.3:
None
se inserta ensys.path_importer_cache
en lugar de una instancia deNullImporter
.Obsoleto desde la versión 3.4: Inserte
None
ensys.path_importer_cache
en su lugar.-
Ejemplos¶
La siguiente función emula lo que era la instrucción de importación estándar hasta Python 1.4 (sin nombres de módulo jerárquico). (Esta implementación no funcionaría en esa versión, ya que find_module()
se ha ampliado y load_module()
se ha añadido en 1.4.)
import imp
import sys
def __import__(name, globals=None, locals=None, fromlist=None):
# Fast path: see if the module has already been imported.
try:
return sys.modules[name]
except KeyError:
pass
# If any of the following calls raises an exception,
# there's a problem we can't handle -- let the caller handle it.
fp, pathname, description = imp.find_module(name)
try:
return imp.load_module(name, fp, pathname, description)
finally:
# Since we may exit via an exception, close fp explicitly.
if fp:
fp.close()