Lección 41 de 45 · Calidad y depuración

Typing y análisis estático

Haz que una función explique qué recibe y qué devuelve antes de ejecutarla, sin convertir el tipado en una colección de reglas que memorizar.

Paso a pasoLectura de diagnósticosNúcleo + ampliación
Índice · Lección 41/45
La meta de esta lección

No vas a aprender “todos los tipos”. Vas a aprender a escribir contratos pequeños que hagan el código más fácil de entender y revisar.

Ya conoces las anotaciones básicas. Aquí damos el siguiente paso: elegir un tipo que describa lo que la función necesita de verdad.

Evidencia de aprendizaje

Leer un diagnóstico de tipos como “esperaba X, recibió Y” y corregir el contrato o el uso según la intención.

Un type hint es una señal, no una barrera

Cuando escribes nombre: str o -> int, Python no coloca un guardia delante de la función. La anotación sirve sobre todo para que una persona —y herramientas como un analizador estático— puedan detectar incoherencias antes de ejecutar el programa.

Primero, separa anotación de validación
def repetir(texto: str, veces: int) -> str:
    return texto * veces

print(repetir("Py", 3))
  1. texto: str comunica que esperamos texto.
  2. veces: int documenta la cantidad de repeticiones.
  3. -> str hace visible qué sale de la función.

Idea importante: una anotación no sustituye una comprobación de datos externos. Si un formulario, archivo o API puede traer valores incorrectos, todavía debes validarlos.

Describe la forma del dato que circula

Los tipos se vuelven especialmente útiles cuando una variable contiene una colección. Leer list[str] te cuenta mucho más que leer simplemente list: sabes que existe una lista y que cada elemento debería ser texto.

Colecciones que cuentan su propia historia
def contar_palabras(palabras: list[str]) -> dict[str, int]:
    conteo = {}
    for palabra in palabras:
        conteo[palabra] = conteo.get(palabra, 0) + 1
    return conteo

print(contar_palabras(["sol", "luna", "sol"]))

Lee la cabecera en voz alta: “esta función recibe una lista de textos y devuelve un diccionario que relaciona texto con entero”. Si la anotación se puede traducir a una frase sencilla, está cumpliendo su función.

Una duda frecuente: ¿hay que anotar cada variable?

No. Para empezar, prioriza parámetros, retornos y datos compartidos entre partes del programa. Anotar cada variable local puede añadir ruido sin mejorar la comprensión.

Ampliación: pedir capacidades más generales

Más adelante podrás usar tipos como Iterable[float] cuando una función solo necesite recorrer valores. Para el objetivo de esta lección basta con leer diagnósticos usando tipos básicos y colecciones como list[int].

Lee el diagnóstico: “esperaba X, recibió Y”

Aviso simulado de un analizador estático
Argument of type "str" cannot be assigned to parameter "numero" of type "int"
Esperaba: int
Recibió: str

El programa puede llegar a ejecutarse, pero el aviso te señala una incoherencia entre el contrato escrito y el uso real. Decide cuál expresa tu intención antes de “silenciar” la herramienta.

La función promete un entero, pero la llamada le entrega texto. Corrige el uso porque en este caso el dato “3” sí debe convertirse a número.

Salida esperada
6
typing.py
La salida aparecerá aquí.

Necesito una pista
  • La anotación de la función expresa la intención correcta.
  • Convierte dato al llamar o antes de llamar.
Ver una solución razonada
def duplicar(numero: int) -> int:
    return numero * 2

dato = "3"
print(duplicar(int(dato)))

Cómo leer un aviso sin sentir que “el programa está mal”

Un analizador estático señala una posible incoherencia entre el contrato escrito y el uso del código. Eso es una pista, no una sentencia. Cuando aparezca un aviso, sigue este orden:

  1. Lee qué valor esperaba.
  2. Mira qué valor está llegando.
  3. Decide cuál de los dos representa tu intención real.
  4. Corrige el código o el tipo; no cambies el tipo solo para silenciar la herramienta.
Ya puedes cerrar el módulo 8 cuando…

puedes leer una firma como def buscar(ids: list[int]) -> str | None, explicarla en palabras y distinguir entre “esto es una anotación” y “esto valida datos en tiempo de ejecución”.