- Presenta 14 funciones avanzadas de Python poco conocidas, junto con ejemplos reales
- Ofrece una explicación profunda sobre tipado estático y diseño estructural, incluyendo
typing, generics, protocols y context managers
- También incluye pattern matching estructural introducido desde Python 3.10, además de técnicas de optimización de rendimiento como slots y metaclasses
- Reúne consejos para escribir código más limpio como
f-string, cache, future, proxy, for-else y walrus
- Proporciona enlaces y materiales de referencia para seguir aprendiendo en cada función, con una estructura accesible incluso para desarrolladores junior
Resumen de 14 funciones avanzadas de Python
# Sobrecarga de tipado
- El decorador
@overload permite definir múltiples firmas de tipos para una sola función
- El verificador de tipos puede inferir con precisión el tipo de retorno según los argumentos recibidos
- También es posible restringir valores de cadenas usando
Literal
- Se puede implementar una firma de función que requiera solo uno de
id o username
Literal puede usarse como una alternativa ligera a Enum para mejorar la seguridad de tipos
# Argumentos solo por palabra clave / solo posicionales
- Con
* se pueden definir argumentos solo por palabra clave (no se permiten argumentos posicionales)
- Con
/ se pueden definir argumentos solo posicionales (no se permiten argumentos por palabra clave)
- Esto permite forzar con claridad la forma de usar los argumentos al diseñar una API
# Anotaciones futuras (__future__)
- Como los type hints normalmente se evalúan de inmediato en tiempo de ejecución, pueden surgir problemas con el orden de declaración
- Con
from __future__ import annotations es posible posponer el momento de evaluación
- Sin embargo, como se manejan como cadenas, hay que tener cuidado al usar tipos en tiempo de ejecución
PEP 649 propone una mejora con evaluación diferida en el atributo __annotations__
# Sintaxis genérica (Generic)
- Desde Python 3.12 se admite una nueva sintaxis para definir tipos genéricos
- En lugar de
TypeVar, se puede usar de forma más intuitiva una forma como class Foo[T, U: int]
- También se introducen los genéricos variádicos (Variadic Generics) para manejar distintos tipos
- La definición de alias de tipos también se simplifica, con formas como
type Vector = list[float]
# Protocolos (Protocols)
- Permiten implementar subtipado estructural como una versión de verificación de tipos del Duck Typing
- Si una clase tiene ciertos métodos, puede ser compatible a nivel de tipos incluso sin herencia explícita
- Con
@runtime_checkable también se puede extender para permitir verificaciones con isinstance
# Context manager
- Son objetos con métodos
__enter__ y __exit__ que se usan dentro de bloques with
- Con el decorador
contextlib.contextmanager se puede hacer una implementación simple basada en funciones
- Antes y después de
yield se realizan tareas de configuración y limpieza
# Pattern matching estructural
- La sintaxis
match-case permite ramificar de forma intuitiva estructuras de datos complejas
- Se pueden usar desestructuración de tuplas/listas, patrones OR, condiciones de guarda (
if) y comodines
- Como la ramificación se hace según la estructura de los datos, mejora la legibilidad y mantenibilidad
# Optimización con __slots__
- Usar slots fijos en lugar de
__dict__ permite optimizar memoria y velocidad
__slots__ usa una tupla donde solo se especifican los nombres de atributos
- Evita agregar atributos innecesarios a la clase
- Aun así, como es una microoptimización, conviene usarlo con criterio
# Colección de consejos de estilo para código Python
- Sentencia for-else: ejecuta
else si el bucle termina sin break
- Operador walrus (
:=): permite declarar y evaluar una variable al mismo tiempo
- Cortocircuito con
or: devuelve el primer valor verdadero entre varios
- Encadenamiento de operadores de comparación: permite simplificar código como
0 < x < 10
# Formato avanzado con f-string
- La sintaxis
f"{변수=}" permite mostrar expresiones útiles para depuración
- Incluye varias opciones como formato numérico (
:.2f, :+.2f, :,) y formato de fecha (%Y-%m-%d)
- También se puede aprovechar el mini lenguaje de formato para centrado, relleno y porcentajes
# Decoradores de caché
@lru_cache y @cache permiten guardar resultados de funciones para mejorar la velocidad
- Son útiles en funciones recursivas o en cálculos repetitivos
@cache fue introducido en Python 3.9 y ofrece una caché ilimitada por defecto
# Future en Python
- Ofrece una forma de manejar objetos asíncronos similar a las Promise de JS
- Con
Future.set_result() y add_done_callback() se pueden administrar resultados de forma asíncrona
asyncio.Future() puede usarse junto con await
- Al usarlo con
ThreadPoolExecutor, también permite procesamiento paralelo en segundo plano
# Propiedad proxy (Proxy Property)
- Permite que un atributo de clase funcione tanto como propiedad como función
- Proporciona ambas capacidades mediante
__get__, __call__ y __repr__
- En diseño de API, permite manejar valores predeterminados y llamadas con parámetros en una sola interfaz
- Más que para uso práctico, vale como ejemplo experimental
# Metaclases
- Son la clase de las clases, encargadas de crear las propias clases
- Permiten lógica meta como manipular atributos de clase o registro automático
- En la práctica, muchas veces pueden sustituirse por decoradores
- Frameworks como Django, SQLAlchemy y Pydantic usan metaclases internamente
5 comentarios
Desde la perspectiva del backend, he tenido la experiencia de que las metaclases dificultan la depuración.
Ten en cuenta que
for-elsea menudo se considera un antipatrón porque existe la opinión de que no ofrece buena legibilidad ni claridad, y queasyncio.Futurese trata como un detalle de implementación interno deasyncio.Gracias. Especialmente el punto 10, lo aplico de inmediato.
Agregar reglas de programación con IA..
Gracias por el gran consejo.
Opiniones de Hacker News
¡Hola! ¡Soy el autor original del blog! Me sorprendió ver mi texto en la portada de HN a las 4 de la mañana
Cada vez que uso Python me preocupa que mi código parezca como si estuviera usando Python de forma incorrecta
Python debería seguir siendo Python, y golang, Rust y Typescript deberían mantener cada uno su propia filosofía y diseño
La mayor fortaleza de Python es que se siente como seudocódigo ejecutable
Observación sobre la sección 9.3 de evaluación de expresiones: si hay una cadena vacía, la evaluación se realiza de manera distinta
Como alguien que se cambió de Javascript/Typescript a Python, este fue un recurso útil
La mayoría de las funciones no son avanzadas
Lo que cambiaría de la lista es la inclusión de los contenedores de collections.abc
Disfruté leer este texto