Curso de Python / Documentar contratos con anotaciones de tipos

Las anotaciones de tipos describen las entradas y resultados que espera una función para sus lectores y herramientas de análisis. La ejecución ordinaria de Python no las aplica automáticamente: anotar un argumento como int no lo convierte ni valida su rango.

Leer el contrato de una función

En amount: int, el tipo esperado es un entero. La anotación -> str describe un resultado de texto. list[int] expresa una lista de enteros y str | None permite una cadena o la ausencia de resultado. Los ejemplos del curso utilizan Python 3.12 o posterior.

Estas indicaciones ayudan al editor y a un comprobador estático a detectar llamadas incompatibles. No comprueban que exista un archivo, que responda una red o que un importe tenga sentido comercial. Si un programa inspecciona anotaciones dinámicamente, también debe revisar las reglas de evaluación de su versión de Python.

Comparar anotaciones y comprobaciones explícitas

Guarda este programa como hints.py y ejecútalo con python hints.py. La llamada incorrecta al final es intencionada y está capturada para observar la validación.

def format_amount(amount: int) -> str:
    if type(amount) is not int or amount < 0:
        raise ValueError("invalid amount")
    return f"{amount:,} KRW"

def find_name(names: dict[str, str], key: str) -> str | None:
    return names.get(key)

print(format_amount(8000))
print(find_name({"e1": "lunch"}, "missing"))
try:
    format_amount("8000")
except ValueError:
    print("rejected")
8,000 KRW
None
rejected

El texto rejected aparece porque el cuerpo de format_amount ejecuta una comprobación y lanza ValueError, no porque Python imponga la anotación. El resultado None de find_name también está previsto en su contrato.

Añadir un análisis estático opcional

Si quieres comparar ambos mecanismos, instala mypy en el entorno virtual del proyecto y analiza el mismo archivo:

python -m pip install mypy
python -m mypy hints.py

La llamada format_amount("8000") debe producir un diagnóstico de argumento incompatible. El texto exacto depende de la versión del comprobador. En una copia del archivo, retira esa llamada deliberadamente incorrecta y repite el análisis para observar el caso correcto.

No conviertas todos los tipos en Any solo para silenciar advertencias. Decide si una entrada externa de texto debe convertirse a entero o rechazarse, realiza esa operación en la frontera de entrada y mantén el cálculo con un contrato claro. La guía de ejecución de mypy explica el análisis y sus opciones.

Mecanismo Comprobación
Análisis estático Relaciones entre tipos declarados y usos del código
Validación en ejecución Valores recibidos, rangos y estructura de datos

Tratar los resultados que pueden faltar

Antes de llamar a un método de cadena sobre el resultado de find_name, comprueba si es None. Haz que la anotación coincida con todas las rutas de retorno; quien llama no debería adivinar si puede faltar un valor.

Las excepciones expresan fallos en ejecución y las pruebas automatizadas comprueban resultados concretos de forma repetible. Combina esas herramientas con las anotaciones según su función. La referencia de typing detalla el sistema de tipos y recuerda sus límites en tiempo de ejecución.