importlib — Mecanismo de importación de Python¶
Propósito: | El módulo importlib expone la implementación de la declaración de importación de Python. |
---|
El módulo importlib
incluye funciones que implementan el mecanismo de
importación de Python para cargar código en paquetes y módulos. Es un punto de
acceso para importar módulos dinámicamente, y es útil en algunos casos donde el
nombre del módulo que debe importarse es desconocido cuando se escribe el
código (por ejemplo, para complementos o extensiones de una aplicación).
Paquete de ejemplo¶
Los ejemplos en esta sección usan un paquete llamado example
con
__init__.py
.
print('Importing example package')
El paquete también contiene submodule.py
.
print('Importing submodule')
Está atento al texto de las llamadas print()
en la salida de muestra cuando
se importa el paquete o el módulo.
Tipos de modulo¶
Python admite varios estilos de módulos. Cada uno requiere su propio manejo al
abrir el módulo y agregarlo al espacio de nombres, y el soporte para los
formatos varía según la plataforma. Por ejemplo, en Microsoft Windows, las
bibliotecas compartidas se cargan desde archivos con extensiones .dll
o
.pyd
, en lugar de .so
. Las extensiones para los módulos C también
pueden cambiar cuando se utiliza una compilación de depuración del intérprete
en lugar de una compilación de lanzamiento normal, ya que también se pueden
compilar con información de depuración incluida. Si una biblioteca de
extensión C u otro módulo no se carga como se esperaba, usa las constantes
definidas en importlib.machinery
para encontrar los tipos admitidos para la
plataforma actual y los parámetros para cargarlos.
import importlib.machinery
SUFFIXES = [
('Source:', importlib.machinery.SOURCE_SUFFIXES),
('Debug:',
importlib.machinery.DEBUG_BYTECODE_SUFFIXES),
('Optimized:',
importlib.machinery.OPTIMIZED_BYTECODE_SUFFIXES),
('Bytecode:', importlib.machinery.BYTECODE_SUFFIXES),
('Extension:', importlib.machinery.EXTENSION_SUFFIXES),
]
def main():
tmpl = '{:<10} {}'
for name, value in SUFFIXES:
print(tmpl.format(name, value))
if __name__ == '__main__':
main()
El valor de retorno es una secuencia de tuplas que contienen la extensión del archivo, el modo a utilizar para abrir el archivo que contiene el módulo y un código de tipo de una constante definida en el módulo. Esta tabla está incompleta, porque algunos de los tipos de módulos o paquetes importables no corresponden a archivos individuales.
$ python3 importlib_suffixes.py
Source: ['.py']
Debug: ['.pyc']
Optimized: ['.pyc']
Bytecode: ['.pyc']
Extension: ['.cpython-36m-darwin.so', '.abi3.so', '.so']
Importar Módulos¶
La interfaz de programación de alto nivel en importlib
simplifica la
importación de un módulo con un nombre absoluto o relativo. Cuando utilizas un
nombre de módulo relativo, especifica el paquete que contiene el módulo como un
argumento separado.
import importlib
m1 = importlib.import_module('example.submodule')
print(m1)
m2 = importlib.import_module('.submodule', package='example')
print(m2)
print(m1 is m2)
El valor de retorno de import_module()
es el objeto del módulo creado por
la importación.
$ python3 importlib_import_module.py
Importing example package
Importing submodule
<module 'example.submodule' from '.../example/submodule.py'>
<module 'example.submodule' from '.../example/submodule.py'>
True
Si el módulo no se puede importar, import_module()
genera ImportError
.
import importlib
try:
importlib.import_module('example.nosuchmodule')
except ImportError as err:
print('Error:', err)
El mensaje de error incluye el nombre del módulo que falta.
$ python3 importlib_import_module_error.py
Importing example package
Error: No module named 'example.nosuchmodule'
Para volver a cargar un módulo existente, usa reload()
.
import importlib
m1 = importlib.import_module('example.submodule')
print(m1)
m2 = importlib.reload(m1)
print(m1 is m2)
El valor de retorno de reload()
es el nuevo módulo. Dependiendo del tipo
de cargador utilizado, puede ser la misma instancia de módulo.
$ python3 importlib_reload.py
Importing example package
Importing submodule
<module 'example.submodule' from '.../example/submodule.py'>
Importing submodule
True
Cargadores¶
La interfaz de programación de nivel inferior en importlib
proporciona
acceso a los objetos del cargador, como se describe en Módulos e Importaciones de la
sección sobre el módulo sys
. Para obtener un cargador para un módulo, usa
find_loader()
. Luego, para recuperar el módulo, usa el método
load_module()
del cargador.
import importlib
loader = importlib.find_loader('example')
print('Loader:', loader)
m = loader.load_module()
print('Module:', m)
Este ejemplo carga el nivel superior del paquete example
.
$ python3 importlib_find_loader.py
Loader: <_frozen_importlib_external.SourceFileLoader object at
0x101fe1828>
Importing example package
Module: <module 'example' from '.../example/__init__.py'>
Los submódulos dentro de los paquetes deben cargarse por separado utilizando la
ruta del paquete. En el siguiente ejemplo, el paquete se carga primero y luego
su ruta se pasa a find_loader()
para crear un cargador capaz de cargar el
submódulo.
import importlib
pkg_loader = importlib.find_loader('example')
pkg = pkg_loader.load_module()
loader = importlib.find_loader('submodule', pkg.__path__)
print('Loader:', loader)
m = loader.load_module()
print('Module:', m)
A diferencia de import_module()
, el nombre del submódulo debe darse sin
ningún prefijo de ruta relativo, ya que el cargador ya estará limitado por la
ruta del paquete.
$ python3 importlib_submodule.py
Importing example package
Loader: <_frozen_importlib_external.SourceFileLoader object at
0x101fe1f28>
Importing submodule
Module: <module 'submodule' from '.../example/submodule.py'>
Ver también
- Documentación de la biblioteca estándar para importlib
- Módulos e Importaciones – Ganchos de importación, la ruta de búsqueda del
módulo y otra maquinaria relacionada en el módulo
sys
. inspect
– Cargar información desde un módulo programáticamente.- PEP 302 – Nuevos ganchos de importación.
- PEP 369 – Ganchos post importación.
- PEP 488 – Eliminación de archivos PYO.