Nuestro primer módulo (2ª parte)
Paso 6: Detección del contexto de ejecución
La variable __name__ se puede usar para determinar si el archivo fue ejecutado directamente o importado. Al modificar module.py de la siguiente forma:
if __name__ == "__main__":
print("Yo prefiero ser un módulo")
else:
print("Me gusta ser un módulo")
- Si ejecutas
module.pydirectamente, verás:Yo prefiero ser un módulo. - Si ejecutas
programa1.py, verás:Me gusta ser un módulo.
Este enfoque es útil para realizar pruebas dentro del módulo, que solo se ejecutan cuando el archivo se ejecuta directamente y no cuando se importa.
Paso 7: Agregar un contador al módulo
En este paso, se introduce una variable global contador en el módulo para contar cuántas veces se invocan las funciones:
contador = 0
if __name__ == "__main__":
print("Yo prefiero ser un módulo")
else:
print("Me gusta ser un módulo")
Esta variable se inicializa en 0 cuando el módulo es importado.
Paso 8: Acceso a variables del módulo
El archivo main.py se modifica para acceder a la variable contador:
import module
print(module.contador)
Este código es válido, pero plantea una cuestión sobre la privacidad de las variables. En Python, no existe un mecanismo para ocultar variables a los usuarios del módulo. Sin embargo, es una convención anteponer un guión bajo (_) o dos (__) al nombre de las variables para indicar que son “privadas”. Aunque esto es solo un acuerdo, los usuarios del módulo pueden respetarlo o no.
Paso 9: Añadir funciones al módulo
El módulo se actualiza para incluir dos funciones que calculan la suma y el producto de los elementos de una lista, además de un contador privado:
#!/usr/bin/env python3
""" module.py - Un ejemplo de un módulo en Python """
__contador = 0
def suma(lista):
global __contador
__contador += 1
acumulador = 0
for elemento in lista:
acumulador += elemento
return acumulador
def producto(lista):
global __contador
__contador += 1
acumulador = 1
for elemento in lista:
acumulador *= elemento
return acumulador
if __name__ == "__main__":
print("Yo prefiero ser un módulo, pero puedo realizar algunas pruebas por ti")
mi_lista = [i+1 for i in range(5)]
print(suma(mi_lista) == 15)
print(producto(mi_lista) == 120)
- La línea
#!/usr/bin/env python3indica al sistema operativo qué programa debe usar para ejecutar el archivo (importante en sistemas Linux). - El doc-string (
""" module.py - Un ejemplo de un módulo en Python """) proporciona una breve descripción del módulo. - Las funciones
suma()yproducto()están disponibles para ser importadas y cuentan cuántas veces son llamadas mediante la variable__contador. - La variable
__name__se usa para ejecutar pruebas si el archivo es ejecutado directamente.
Paso 10: Usar el módulo
Finalmente, el módulo puede usarse desde el archivo programa1.py de la siguiente manera:
from module import suma, producto
ceros = [0 for i in range(5)]
unos = [1 for i in range(5)]
print(suma(ceros)) # Salida: 0
print(producto(unos)) # Salida: 1
Este código importa las funciones del módulo y las utiliza para calcular la suma y el producto de los elementos en las listas ceros y unos.
Paso 11: Cómo Python busca los módulos
En este paso, el escenario cambia y el archivo principal (programa1.py) se encuentra en una carpeta diferente a la del módulo. El ejemplo asume el siguiente entorno Linux:
programa1.pyestá en:~/python/programas- El módulo está en:
~/python/modulos
Python busca los módulos en las carpetas especificadas en una lista llamada sys.path. Para verificar esta lista, se puede usar el siguiente código:
import sys
for p in sys.path:
print(p)
Este código imprime las rutas que Python examina al buscar módulos. El primer elemento es la carpeta desde donde se ejecuta el script, seguida de varias otras rutas predeterminadas (como el directorio de instalación de Python y las bibliotecas de terceros). También puede incluir archivos .zip, ya que Python puede tratarlos como si fueran carpetas.
Para que Python encuentre el módulo en un directorio diferente, puedes modificar la lista sys.path agregando la carpeta correspondiente.
Paso 12: Añadir una ruta a sys.path
Para que Python pueda encontrar el módulo en una carpeta diferente, se puede agregar su ruta, lo vemos en el archivo programa2.py:
from sys import path
path.append('../modulos') # Añade la carpeta 'modulos' a sys.path
import module
ceros = [0 for i in range(5)]
unos = [1 for i in range(5)]
print(module.suma(ceros)) # Salida: 0
print(module.producto(unos)) # Salida: 1
- Rutas relativas: En el ejemplo, se usa una ruta relativa (
../modulos), lo que significa que Python buscará la carpetamodulosubicada un nivel por encima del directorio actual. Esta solución funciona siprograma2.pyse ejecuta desde la carpeta adecuada.
- Rutas absolutas: Si prefieres asegurarte de que Python siempre encuentra el módulo, puedes usar una ruta absoluta:
path.append('~/python/modulos') - Método
append(): Añade la nueva ruta al final de la listasys.path. Si prefieres que la nueva ruta sea la primera en ser buscada, puedes usarinsert()en lugar deappend().
Este método asegura que Python pueda importar módulos desde cualquier ubicación en el sistema, según las rutas agregadas a sys.path.