Módulos en Python: import, from/import, __name__ y entornos virtuales con venv

Los módulos son la unidad de organización del código en Python: cada fichero .py es un módulo. Entender cómo funciona import, para qué sirve __name__ y cómo crear entornos virtuales aislados son habilidades fundamentales para cualquier proyecto Python real.

import básico y variantes

# Importar el módulo completo (acceso con nombre calificado)
import math
print(math.pi)          # 3.141592...
print(math.sqrt(16))    # 4.0

# Importar nombres específicos
from math import pi, sqrt, ceil
print(pi)       # 3.141592...
print(sqrt(25)) # 5.0

# Alias para nombres largos o conflictivos
import collections.abc as abc
from datetime import datetime as dt

ahora = dt.now()
print(ahora.strftime("%Y-%m-%d %H:%M"))

# Evita 'from modulo import *' en código de producción:
# contamina el espacio de nombres y dificulta saber de dónde viene cada nombre

__name__ == '__main__'

Cuando Python ejecuta un fichero directamente, establece __name__ a '__main__'. Cuando el fichero es importado como módulo, __name__ toma el nombre del módulo. Este patrón protege el código de ejecución de correr cuando el módulo se importa:

# matematicas.py

def sumar(a, b):
    return a + b

def restar(a, b):
    return a - b

# Este bloque solo se ejecuta cuando corres el fichero directamente
if __name__ == "__main__":
    # Código de prueba o demo
    print(sumar(3, 4))    # 7
    print(restar(10, 3))  # 7

# Si otro fichero hace 'import matematicas', este bloque NO se ejecuta

Crear módulos y paquetes propios

# Estructura de un paquete:
# mi_proyecto/
# ??? __init__.py          # convierte el directorio en paquete
# ??? utils/
# ?   ??? __init__.py
# ?   ??? texto.py
# ?   ??? numeros.py
# ??? main.py

# utils/texto.py
def capitalizar(s):
    return s.title()

# utils/__init__.py — exporta lo que quieres hacer público
from .texto import capitalizar

# main.py
from utils import capitalizar
# o bien
from utils.texto import capitalizar
# Importación relativa dentro de un paquete
# utils/numeros.py
from .texto import capitalizar    # importa del mismo paquete (relativa)
# from utils.texto import capitalizar  # importación absoluta (también válida)

Entornos virtuales con venv

# Crear un entorno virtual (en terminal, no en Python)
# python -m venv mi_entorno

# Activar:
# Linux/Mac:  source mi_entorno/bin/activate
# Windows:    mi_entornoScriptsactivate

# Desactivar:
# deactivate

Gestión de dependencias con pip y requirements.txt

# Instalar paquetes (con el entorno activado)
# pip install requests pandas

# Guardar las dependencias del proyecto
# pip freeze > requirements.txt

# Instalar dependencias en otro entorno
# pip install -r requirements.txt

# Ver paquetes instalados
# pip list

# Actualizar un paquete
# pip install --upgrade requests

# Desinstalar
# pip uninstall requests

Inspeccionar módulos

import math

# Ver todos los nombres del módulo
print(dir(math))

# Ayuda de una función
help(math.sqrt)

# Dónde está el fichero del módulo
print(math.__file__)

# Para módulos propios: recargar después de modificar
import importlib
importlib.reload(math)

# Listar solo los no-privados
publicos = [n for n in dir(math) if not n.startswith("_")]
print(publicos)

Evitar dependencias circulares

# modulo_a.py importa modulo_b, y modulo_b importa modulo_a ? circular

# Soluciones:
# 1. Mover el código compartido a un tercer módulo (utils.py)
# 2. Importar dentro de la función que lo necesita (importación tardía)

def mi_funcion():
    from modulo_b import algo  # importación tardía — evita el circular
    return algo()

La regla general: un entorno virtual por proyecto, siempre. El requirements.txt (o mejor aún, pyproject.toml con un gestor moderno como uv) documenta las dependencias. El patrón if __name__ == "__main__" es obligatorio en cualquier módulo que tenga tanto lógica reutilizable como código de ejecución directa.

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP