Importar un módulo Python dinámicamente

Para poder utilizar un mismo código Python que tenía duplicado con distintas configuraciones en distintos directorios pensé en poner las variables que definen la configuración del trabajo a realizar en ficheros .py particulares y cargarlos como un módulo desde el ahora único fichero de código con lógica. Pensé en esta chapuza de ficheros de configuración para ahorrarme trabajo y no tener que analizar archivos JSON, YAML o cualquier otro formato. Al final el trabajo me lo ahorré gracias a un experto en Python que trabaja conmigo.

Para resumir digamos que tengo X ficheros Python del estilo de estos dos:

#!/usr/bin/python
#Configuración 1
variable = "Por aquí"
#Lógica
print variable
#!/usr/bin/python
#Configuración 2
variable = "Por allá"
#Lógica
print variable

Lo que quería hacer es tener un fichero único con la lógica y un fichero particular por cada configuración importado desde el fichero de lógica. Así, los ficheros de configuración serían los siguientes:

#!/usr/bin/python
#Configuración 1
variable = "Por aquì"
#!/usr/bin/python
#Configuración 2
variable = "Por allá"

Al fichero de lógica le proporcionaría la ruta del fichero de configuración a importar y listo. Pero en el fichero de lógica no se puede utilizar un simple import, ya que el nombre de los ficheros de configuración a importar es dinámico.

Buscando por ahí llegué hasta el punto en que teniendo la ruta del fichero de configuración preparada, lograba (más o menos) importar el fichero de configuración utilizando el módulo importlib. Aclaro que el entorno en el que trabajo es Python 2.7, aunque creo, que esto funciona igual en Python 3. Con la documentación y los artículos que había leído llegué hasta este código que requiere como primer parámetro la ruta del directorio donde buscar el módulo y como segundo el nombre del módulo (nombre del fichero eliminando el sufijo .py):

#!/usr/bin/python
import os
import sys
# Obvio las comprobaciones de número de parámetros y existencia de rutas
directorioConfiguracion = os.path.abspath(sys.argv[1])
nombreModulo = sys.argv[2]

# Aquí se le dice donde buscar el módulo
sys.path.append(directorioConfiguracion)

# Aquí trato (sin éxito aún) de importarlo correctamente
import importlib
importlib.import_module(nombreModulo)

# Aquí se ve que el módulo se ha "cargado" con el nombre proporcionado como nombreModulo
print sys.modules

El módulo era encontrado y cargado, pero no veía la forma de poder acceder a las variables que había en él. Y, (muy) probablemente, seguiría sin verla mientras escribo esto de no haber consultado al mencionado experto compañero. Él, echando un vistazo me dijo: “¿no tendrías que asignar el resultado del import_module a una variable?”. Ahora me parece obvio que debía ser así.

Así, el código correcto resultó ser el siguiente:

#!/usr/bin/python
import os
import sys
# Obvio las comprobaciones de número de parámetros y existencia de rutas
directorioConfiguracion = os.path.abspath(sys.argv[1])
nombreModulo = sys.argv[2]

# Aquí se le dice donde buscar el módulo
sys.path.append(directorioConfiguracion)

# Aquí trato (sin éxito aún) de importarlo correctamente
import importlib
moduloConfiguracion = importlib.import_module(nombreModulo)

#Lógica
print moduloConfiguracion.variable


Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.