¿Qué son los Type Hints en Python?
Los Type Hints (anotaciones de tipos) son un sistema para indicar los tipos de datos esperados en el código Python, lo que mejora la legibilidad, fiabilidad y calidad del software. Aunque Python sigue siendo un lenguaje de tipado dinámico, la posibilidad de especificar tipos explícitamente ayuda a evitar muchos errores durante el desarrollo.
¿Por qué usar anotaciones de tipos?
Python es conocido por su flexibilidad, pero esto a menudo genera errores ocultos debido a tipos de datos inesperados. Veamos un ejemplo sin anotaciones:
def add(a, b):
return a + b
print(add(5, 10)) # 15
print(add("5", "10")) # '510' — resultado inesperado
La expresión add("5", "10") no genera un error, pero el resultado puede ser sorprendente para el desarrollador.
Los Type Hints resuelven los siguientes problemas:
- Indicación explícita de tipos de argumentos y valores de retorno
- Mejora de la legibilidad del código para el equipo de desarrollo
- Análisis estático para detectar errores antes de ejecutar el programa
- Autocompletado en IDE con sugerencias más precisas
- Documentación de API sin necesidad de comentarios adicionales
Ejemplos básicos de Type Hints
Anotaciones en funciones
def add(a: int, b: int) -> int:
return a + b
def calculate_area(radius: float) -> float:
return 3.14159 * radius ** 2
def format_greeting(name: str) -> str:
return f"¡Hola, {name}!"
Anotaciones en variables
name: str = "Ana"
age: int = 30
pi: float = 3.14159
is_active: bool = True
Trabajo con colecciones
from typing import List, Dict, Tuple, Set
def process_scores(scores: List[int]) -> float:
return sum(scores) / len(scores)
def get_user_data() -> Dict[str, str]:
return {"name": "Juan", "email": "juan@ejemplo.com"}
def get_coordinates() -> Tuple[float, float]:
return (10.5, 20.3)
def unique_values(items: List[str]) -> Set[str]:
return set(items)
Funcionalidades avanzadas de Type Hints
Optional y Union
from typing import Optional, Union
def greet(name: Optional[str] = None) -> str:
if name:
return f"¡Hola, {name}!"
return "¡Hola, Invitado!"
def process_value(value: Union[int, float, str]) -> str:
return str(value)
# En Python 3.10+ se puede usar el operador |
def process_new_syntax(value: int | float | str) -> str:
return str(value)
Tipos Callable
from typing import Callable
def apply_function(func: Callable[[int, int], int], a: int, b: int) -> int:
return func(a, b)
def multiply(x: int, y: int) -> int:
return x * y
result = apply_function(multiply, 5, 3) # 15
Tipos Genéricos (Generic)
from typing import TypeVar, Generic, List
T = TypeVar('T')
class Stack(Generic[T]):
def __init__(self) -> None:
self.items: List[T] = []
def push(self, item: T) -> None:
self.items.append(item)
def pop(self) -> T:
if not self.items:
raise IndexError("La pila está vacía")
return self.items.pop()
def is_empty(self) -> bool:
return len(self.items) == 0
# Uso
int_stack = Stack[int]()
int_stack.push(42)
Anotaciones en clases
from typing import List, Optional
from dataclasses import dataclass
class Person:
def __init__(self, name: str, age: int, email: Optional[str] = None) -> None:
self.name = name
self.age = age
self.email = email
def greet(self) -> str:
return f"Me llamo {self.name} y tengo {self.age} años."
# Uso
person = Person("Carlos", 28, "carlos@ejemplo.com")
print(person.greet())