imp — Acceda a import internamente

Código fuente: Lib/imp.py

Obsoleto desde la versión 3.4, se eliminará en la versión 3.12: El módulo imp está obsoleto en favor de importlib.


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 incorporada open() 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 valores PY_SOURCE, PY_COMPILED, o C_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 por sys.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 provoca ImportError. 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 es PKG_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() y load_module() para buscar y cargar el paquete P, y luego use find_module() con el argumento path establecido en P.__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 use importlib.find_loader(). Para ver el uso del caso anterior, consulte la sección Ejemplos de la documentación importlib.

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 ser None 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 por get_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ón tryfinally.

Obsoleto desde la versión 3.3: Si se utiliza anteriormente junto con imp.find_module() considere usar importlib.import_module(), de lo contrario utilice el cargador retornado por el reemplazo que eligió para imp.find_module(). Si llamó a imp.load_module() y funciones relacionadas directamente con argumentos de ruta de archivo, utilice una combinación de importlib.util.spec_from_file_location() y importlib.util.module_from_spec(). Consulte la sección Ejemplos de la documentación importlib 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__ y builtins. 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 fromimport …, llamando a reload() para el otro módulo no redefine los objetos importados de él — de una manera alrededor de esto es volver a ejecutar la sentencia from, otra es usar import 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 cadena cpython-32 proviene de la etiqueta mágica actual (consulte get_tag(); si sys.implementation.cache_tag no está definida entonces NotImplementedError se generará). Al pasar True o False 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 define sys.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 un ValueError. Si sys.implementation.cache_tag no está definido, se genera NotImplementedError.

Distinto en la versión 3.3: Provoca NotImplementedError cuando no se define sys.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 retorna False.

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 genera ImportError. De lo contrario, se retorna una instancia NullImporter.

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 en sys.path_importer_cache en lugar de una instancia de NullImporter.

Obsoleto desde la versión 3.4: Inserte None en sys.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()