Tema: python
-
Python 3.10 tras el fin de su vida útil: localizar intérpretes y reconstruir entornos
La tabla de ciclo de vida del proyecto Python sitúa el fin de la vida útil de Python 3.10 el 1 de octubre de 2026. Inventariar los intérpretes que utilizan realmente los servicios, entornos virtuales e imágenes y, después, reconstruir y probar cada aplicación en una rama con soporte.
-
Diseñar una herramienta de línea de comandos en Python: argparse, main() y códigos de salida
Colocar la interfaz en una función main(argv) -> int registrada como console script, validar con type y choices de argparse, seguir la convención de códigos de salida (0 éxito, 2 error de uso, 1 otro fallo, códigos de sysexits solo si están documentados), mantener los resultados en stdout y los diagnósticos en stderr, y gestionar SIGINT y las tuberías rotas.
-
Bootstrapping de un intervalo de confianza para una mediana, un percentil o una razón
Remuestrear las observaciones brutas con reemplazo muchas veces, calcular el estadístico en cada remuestra, y leer el intervalo a partir de la distribución resultante; esto da una incertidumbre para medianas, percentiles, razones y diferencias donde no se aplica ninguna fórmula de manual. Reportar el método, el número de remuestras y el tamaño de la muestra, y no confiar en él para percentiles extremos de muestras pequeñas.
-
Vincular la identidad de publicación en npm y PyPI con los artefactos aprobados de cada versión
La publicación de confianza mediante OIDC elimina los tokens de publicación almacenados, pero su seguridad sigue dependiendo del flujo de trabajo autorizado. Separar la compilación de la publicación, proteger las aprobaciones y verificar la identidad del artefacto sin interpretar su procedencia como un veredicto sobre la presencia de malware.
-
Pruebas basadas en propiedades con entradas generadas
En lugar de ejemplos elegidos a mano, una prueba basada en propiedades enuncia un invariante y deja que una biblioteca genere muchas entradas, reduciendo los fallos a contraejemplos mínimos; Hypothesis es la implementación de referencia para Python.
-
Gestores de contexto en Python: garantizar la limpieza
La sentencia with ejecuta __enter__ y __exit__ alrededor de un bloque para que los archivos, los bloqueos y las conexiones se liberen incluso cuando ocurre una excepción; contextlib.contextmanager convierte un generador en uno de ellos.
-
Docstrings que las herramientas y las personas lectoras pueden usar
El PEP 257 define dónde van los docstrings y cómo se formatean; un estilo consistente (Google o NumPy) con un resumen de una línea, descripciones de argumentos y de retorno y las excepciones lanzadas los hace utilizables por lectores, editores y generadores de documentación.
-
Números en coma flotante: por qué 0.1 + 0.2 no es 0.3
La coma flotante binaria representa la mayoría de las fracciones decimales de forma aproximada, por lo que la aritmética acumula error de redondeo; conviene comparar con tolerancias, sumar con cuidado, usar enteros o tipos decimales para dinero y recuentos, e imprimir con suficientes dígitos para permitir una reconversión exacta (round-trip).
-
Cargar YAML de forma segura
Los cargadores completos de YAML pueden instanciar objetos arbitrarios a partir de nodos etiquetados; conviene usar siempre un cargador seguro, fijar la semántica de versión de YAML y validar el resultado contra un esquema antes de usarlo.
-
Dialectos de patrones glob: qué significan * y ** en .gitignore, .dockerignore, bash, Python y GitHub Actions
Los mismos caracteres de asterisco simple y doble significan cosas distintas según dónde se evalúe el patrón: un patrón de .gitignore sin barra coincide a cualquier profundidad, mientras que la misma línea en .dockerignore solo coincide en la raíz del contexto; la recursión con globstar de bash es opcional y fnmatch de Python ni siquiera reconoce rutas.
-
Cuándo ayuda asyncio y cuándo no
asyncio ejecuta muchas tareas limitadas por E/S en un solo hilo suspendiéndose en los puntos await; no acelera el código limitado por CPU, y las llamadas bloqueantes dentro de las corrutinas paralizan todo el bucle.
-
El formateo y el linting automatizados como contrato de equipo
Delegar el formato en un formateador y las comprobaciones mecánicas en un linter elimina los debates de estilo de la revisión; EditorConfig, PEP 8 y herramientas como Ruff muestran cómo puede codificarse el contrato en el repositorio.
-
Clases Protocol: tipado estructural para el duck typing de Python
Un typing.Protocol declara los métodos y atributos que necesita un consumidor; cualquier objeto que los tenga satisface el tipo sin heredar de él. Definir los protocolos junto al código que depende de ellos, mantenerlos mínimos y usar runtime_checkable solo donde isinstance sea realmente necesario.
-
Encontrar una fuga de memoria con instantáneas de tracemalloc
Iniciar el rastreo pronto con PYTHONTRACEMALLOC o tracemalloc.start(nframe), tomar una instantánea después del calentamiento y otra tras N iteraciones, filtrar el ruido de las importaciones, y leer compare_to(..., 'lineno') para encontrar las líneas cuyo tamaño crece proporcionalmente a N; cambiar a la agrupación 'traceback' para ver quién las llama.
-
El dinero y otras cantidades exactas: usar Decimal, no float
La coma flotante binaria no puede representar exactamente la mayoría de las fracciones decimales, así que las sumas de precios se desvían; el módulo decimal ofrece aritmética decimal exacta con redondeo explícito, y los enteros en unidades menores son una alternativa.
-
Elegir entre hilos, procesos y asyncio para una carga de trabajo en Python
Clasificar primero la ruta crítica: la espera de E/S se ajusta a asyncio (muchas conexiones, bibliotecas asíncronas) o a un pool de hilos (pocas llamadas bloqueantes); el trabajo de CPU en Python puro necesita procesos o una compilación sin GIL (free-threaded); el código nativo que libera el GIL puede usar hilos. Acotar cada pool, elegir explícitamente el método de arranque de los procesos y escribir la ruta de apagado.
-
Dataclasses para registros simples
dataclasses genera __init__, __repr__ y la igualdad a partir de campos anotados; las dataclasses frozen dan objetos de valor inmutables, slots reduce la memoria, y field(default_factory=...) evita valores por defecto mutables compartidos.
-
¿Con qué carga de trabajo supera la compilación de CPython sin GIL (free-threaded) a un pool de procesos en un servicio mixto de E/S y CPU?
Pregunta abierta: la compilación sin GIL elimina el GIL, pero añade sobrecarga en un solo thread y puede volver al GIL cuando se importa una extensión no preparada, mientras que los pools de procesos pagan el coste del pickling y la duplicación de memoria; ¿para qué proporciones de CPU frente a espera, tamaños de conjunto de trabajo y número de núcleos entrega un pool de threads sobre la compilación sin GIL más rendimiento por núcleo?
-
Intentar un ejercicio antes de leer su solución resuelta produce un mejor recuerdo al cabo de un mes de una característica del lenguaje
Hipótesis: para quien trabaja en ingeniería de software y estudia una característica concreta de un lenguaje, como la sentencia match de Python, resolver un ejercicio antes de ver la solución resuelta lleva a un mejor recuerdo diferido y a una mejor transferencia que estudiar primero la solución y luego resolver un ejercicio similar; una prueba propuesta dentro de sujeto con dos características, dos órdenes y una prueba diferida al cabo de un mes, sin ningún resultado reivindicado.
-
Cancelación en asyncio: realizar la limpieza sin engullir CancelledError
Mantener la cancelación observable para quien es dueño de la tarea mientras se liberan los recursos en la ruta interrumpida.
Legible por máquina: JSON