Historia del tema
Las anotaciones de funciones aparecieron en Python 3.0, y el mecanismo de hints de tipo (type hints) se describe en PEP 484, que se agregó en 3.5. Esta herramienta se creó para el análisis estático de código, autocompletado y mejora de la legibilidad; la biblioteca estándar de tipos (typing) permite especificar explícitamente los tipos esperados de variables, argumentos y valores de retorno de funciones.
Problema
Python es un lenguaje dinámico, donde los tipos de variables pueden cambiar durante la ejecución, lo que puede llevar a errores que solo se muestran en la etapa de ejecución del programa. Las anotaciones no afectan la ejecución del código, pero su uso incorrecto puede dar a los programadores una falsa sensación de "tipificación estricta".
Solución
Las anotaciones de tipo se utilizan para la documentación, la verificación automática mediante mypy, pylance, pyright y herramientas similares, así como para la integración con IDEs. Se implementan mediante dos puntos después del nombre del argumento y una flecha después de la lista de parámetros:**
def greet(name: str, times: int = 1) -> None: for _ in range(times): print(f"¡Hola, {name}!") # Anotación correcta para una función que procesa un diccionario from typing import Dict, List def transform(data: Dict[str, List[int]]) -> float: return sum(sum(lst) for lst in data.values()) / 10
Características clave:
¿Puede Python "verificar automáticamente" la conformidad con los tipos declarados en las anotaciones?
¡No! La verificación de tipos solo ocurre mediante herramientas externas de análisis estático, como mypy. En tiempo de ejecución, Python ignora completamente el contenido de las anotaciones.
def f(x: int): return x * 2 print(f('oops')) # Tipo str, ¡no habrá error!
¿Dónde se almacenan las anotaciones y cómo se pueden obtener en tiempo de ejecución, para qué puede ser útil esto?
Se almacenan en un atributo especial annotations:
def add(x: int, y: int) -> int: return x + y print(add.__annotations__) # {'x': <class 'int'>, 'y': <class 'int'>, 'return': <class 'int'>}
Esto es utilizado por bibliotecas de terceros para la validación de datos, autogeneración de documentación, serialización, etc.
¿Se pueden anotar cualquier variable, solo funciones, qué sucederá en el ámbito global?
Se pueden anotar tanto variables locales como globales mediante dos puntos, esto tampoco afecta la ejecución:
index: int = 0 def func(x: 'User') -> None: ...
En un proyecto corporativo, todos los desarrolladores comenzaron a implementar activamente anotaciones, pero los tipos reales de los argumentos de las funciones a menudo no coincidían con los indicados. Python pasaba por alto estos errores, y los errores inesperados surgían solo en lo profundo de la lógica empresarial. No había configuración de mypy.
Ventajas:
Desventajas:
Uso de hints de tipo y ejecución obligatoria de mypy en CI, así como autogeneración de documentación a partir de annotations:
Ventajas:
Desventajas: