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.
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.
def repetir(texto: str, veces: int) -> str:
return texto * veces
print(repetir("Py", 3))texto: strcomunica que esperamos texto.veces: intdocumenta la cantidad de repeticiones.-> strhace 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.
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”
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.
6
La salida aparecerá aquí.
Necesito una pista
- La anotación de la función expresa la intención correcta.
- Convierte
datoal 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:
- Lee qué valor esperaba.
- Mira qué valor está llegando.
- Decide cuál de los dos representa tu intención real.
- Corrige el código o el tipo; no cambies el tipo solo para silenciar la herramienta.
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”.