lunes, 24 de marzo de 2025
Inicio Blog

Novedades de Python 3.13: mejoras clave y ejemplos prácticos

0

Python 3.13, lanzado el 7 de octubre de 2024, introduce mejoras significativas que optimizan el rendimiento y amplían las capacidades del lenguaje. A continuación, exploraremos algunas de las novedades más destacadas, acompañadas de explicaciones detalladas y ejemplos prácticos para principiantes.

1. Nuevo intérprete interactivo mejorado

El intérprete interactivo de Python, conocido como REPL (Read-Eval-Print Loop), ha sido renovado para ofrecer una experiencia más fluida y amigable. Esta herramienta permite a los desarrolladores escribir y ejecutar código en tiempo real, facilitando la experimentación y el aprendizaje.

Características principales:

  • Edición de múltiples líneas: Ahora es posible escribir bloques de código que abarcan varias líneas sin necesidad de usar caracteres especiales o comandos adicionales. Esto facilita la escritura de funciones y estructuras complejas directamente en el intérprete.
  • Historial de comandos mejorado: El nuevo REPL guarda un historial de los comandos ingresados, permitiendo navegar y reutilizar código previamente ejecutado con mayor facilidad.
  • Mensajes de error en color: Los errores y excepciones ahora se muestran con resaltado de color, lo que ayuda a identificar rápidamente la causa de los problemas en el código.

Ejemplo práctico:

>>> def saludo(nombre):
...     print(f"Hola, {nombre}")
...
>>> saludo("Pythonista")
Hola, Pythonista

En este ejemplo, definimos una función saludo que toma un parámetro nombre y luego la llamamos con el argumento «Pythonista». El intérprete muestra la salida directamente, permitiendo una retroalimentación inmediata.

2. Compilador JIT experimental

Python 3.13 introduce un compilador Just-In-Time (JIT) en fase experimental. Un compilador JIT traduce partes del código en tiempo de ejecución, lo que puede mejorar la velocidad de ejecución de los programas al optimizar secciones críticas del código.

¿Qué significa esto para los desarrolladores?

Aunque el JIT está desactivado por defecto en esta versión, los desarrolladores interesados pueden habilitarlo para evaluar sus beneficios en aplicaciones específicas. Es importante destacar que, al ser una característica experimental, su comportamiento y rendimiento pueden variar, y se recomienda utilizarlo con precaución en entornos de producción.

Cómo habilitar el JIT:

Para ejecutar un script con el compilador JIT habilitado, puedes establecer la variable de entorno PYTHONJIT antes de ejecutar tu script:

PYTHONJIT=1 python mi_script.py

Este comando indica al intérprete de Python que active el compilador JIT al ejecutar mi_script.py.

3. Modo sin GIL experimental

El Global Interpreter Lock (GIL) es un mecanismo que limita la ejecución de múltiples hilos en Python, lo que puede ser una restricción en aplicaciones que requieren concurrencia real. Python 3.13 introduce soporte experimental para ejecutar sin el GIL, permitiendo una verdadera concurrencia en aplicaciones multihilo.

Beneficios potenciales:

  • Mejora del rendimiento en sistemas multicore: Al eliminar el GIL, las aplicaciones pueden aprovechar mejor los procesadores multinúcleo, ejecutando hilos en paralelo y mejorando el rendimiento en tareas concurrentes.

Consideraciones importantes:

Dado que esta característica es experimental, es posible que algunas bibliotecas y extensiones de Python no sean compatibles con el modo sin GIL. Se recomienda realizar pruebas exhaustivas antes de utilizar esta funcionalidad en entornos de producción.

Cómo ejecutar Python en modo sin GIL:

Para ejecutar Python sin el GIL, puedes utilizar el ejecutable python3.13t:

python3.13t mi_script.py

Este comando ejecuta mi_script.py en un entorno donde el GIL está deshabilitado.

4. Mejoras en las anotaciones de tipo

Las anotaciones de tipo en Python permiten especificar el tipo de datos que una función espera recibir y/o devolver, lo que facilita la lectura y el mantenimiento del código. En Python 3.13, las anotaciones de tipo ahora soportan valores por defecto, simplificando la definición de funciones y clases genéricas.

¿Por qué es útil?

Las anotaciones de tipo con valores por defecto permiten definir funciones y clases más flexibles y reutilizables, facilitando la creación de código genérico que puede adaptarse a diferentes tipos de datos sin necesidad de sobrecargar funciones o utilizar múltiples versiones de una misma función.

Ejemplo práctico:

from typing import TypeVar, Generic

T = TypeVar('T', default=int)

class Caja(Generic[T]):
    def __init__(self, valor: T):
        self.valor = valor

caja_entera = Caja(10)  # T se infiere como int
caja_texto = Caja("Hola")  # T se infiere como str

En este ejemplo, definimos una clase genérica Caja que puede contener cualquier tipo de dato. Al crear una instancia de Caja con un número entero, el tipo T se infiere como int. Si creamos una instancia con una cadena de texto, T se infiere como str. Esto proporciona flexibilidad al trabajar con diferentes tipos de datos sin necesidad de definir múltiples clases para cada tipo.

5. Actualizaciones en módulos estándar

Python 3.13 incluye varias mejoras y optimizaciones en los módulos de la biblioteca estándar, lo que amplía las funcionalidades disponibles y mejora la eficiencia del lenguaje.

Ejemplos destacados:

  • Módulo argparse: Se ha añadido soporte para marcar argumentos de línea de comandos como obsoletos, lo que facilita la transición y actualización de aplicaciones que utilizan opciones antiguas.
  • Módulo base64: Se han incorporado las funciones z85encode() y z85decode(), que permiten codificar y decodificar datos en el formato Z85, utilizado en aplicaciones que requieren una representación textual de datos binarios.
  • Módulo random: Ahora incluye una interfaz de línea de comandos, permitiendo generar números aleatorios directamente desde la terminal sin necesidad de escribir un script completo.

Ejemplo práctico con argparse:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument 

6. Mejoras en la gestión de errores y mensajes de excepción

Python 3.13 ha introducido mejoras significativas en la gestión de errores y en la presentación de mensajes de excepción, facilitando la identificación y corrección de errores en el código.

Características principales:

  • Coloreado de tracebacks: Los rastreos de excepciones ahora se muestran con resaltado de color de forma predeterminada en el intérprete interactivo, lo que ayuda a identificar rápidamente la causa de los errores.

Ejemplo práctico:

>>> def dividir(a, b):
...     return a / b
...
>>> dividir(10, 0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in dividir
ZeroDivisionError: division by zero

En este ejemplo, al intentar dividir por cero, Python genera un ZeroDivisionError. Con el nuevo resaltado de color en los tracebacks, es más fácil identificar dónde ocurrió el error y cuál fue su causa.

7. Eliminación de módulos obsoletos

En su esfuerzo por mantener el lenguaje limpio y eficiente, Python 3.13 ha eliminado varios módulos que estaban obsoletos o en desuso.

Ejemplos de módulos eliminados:

  • cgi
  • cgitb
  • telnetlib
  • msilib

Impacto para los desarrolladores:

Si tu código utiliza alguno de estos módulos, es importante buscar alternativas modernas y actualizar el código en consecuencia.

8. Mejoras en la documentación y recursos en español

La documentación oficial de Python ha mejorado su soporte para hablantes de español, proporcionando recursos más accesibles para la comunidad hispanohablante.

Características destacadas:

  • Documentación en español: La documentación oficial de Python está disponible en español, facilitando el aprendizaje y la consulta de recursos.
  • Tutoriales y presentaciones: Se han desarrollado presentaciones y tutoriales en español que explican las novedades de Python 3.13 de manera detallada y accesible.

Recursos recomendados:

  • Documentación oficial en español: La documentación oficial de Python está disponible en español, facilitando el aprendizaje y la consulta de recursos.
  • Presentación «¿Qué hay de nuevo en Python 3.13?» Una presentación detallada en GitHub que aborda las novedades de Python 3.13.

Estas mejoras y recursos adicionales en Python 3.13 reflejan el compromiso continuo de la comunidad por optimizar el lenguaje y hacerlo más accesible para desarrolladores de todos los niveles y procedencias.

Fuentes:

Guía de Laravel 12 con caso de uso de ejemplo

0

Aunque han pasado unos días desde que en febrero se lanzase Laravel 12 (tal como anunciamos en nuestro anterior post), hemos querido dar un repaso un tanto especial a las novedades que ésta nueva versión nos presenta. Para ello, además de mostraros las novedades que trae consigo la nueva versión, os presentamos un caso de uso realista en el que hemos aplicado las nuevas funcionalidades y hemos tratado de explicarlas un poco.

Novedades principales de Laravel 12

Laravel 12 presenta principalmente mejoras incrementales:

  • Uso de UUID v7 como identificadores únicos ordenados cronológicamente.
  • Nuevo método del Query Builder nestedWhere() para simplificar consultas complejas.
  • Mejoras en la validación de archivos, especialmente imágenes SVG (restringidas por defecto).
  • Ejecución paralela mejorada con Concurrency::run() manteniendo claves asociativas.
  • Método mejorado para colecciones: range() con pasos variables.
  • Starter Kits renovados con autenticación avanzada incluida.

Caso de uso: Aplicación «Gestor de Tareas»

Instalación del proyecto

composer create-project laravel/laravel:^12.0 gestor-tareas
npm install && npm run dev
php artisan migrate
php artisan storage:link

Migración para tareas

// database/migrations/create_tasks_table.php
public function up() {
    Schema::create('tasks', function (Blueprint $table) {
        $table->uuid('id')->primary(); // UUID v7 por defecto en Laravel 12
        $table->foreignId('user_id')->constrained()->cascadeOnDelete();
        $table->string('titulo');
        $table->text('descripcion')->nullable();
        $table->string('imagen_path')->nullable();
        $table->timestamps();
    });
}

Explicación:
El campo id utiliza UUID v7 automáticamente gracias al trait HasUuids.

Modelo Task

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Concerns\HasUuids;

class Task extends Model {
    use HasUuids;

    protected $fillable = ['titulo', 'descripcion', 'imagen_path', 'user_id'];

    public function user() {
        return $this->belongsTo(User::class);
    }
}

Explicación:
El trait HasUuids asegura que cada tarea creada tenga automáticamente un UUID v7.

Controlador de tareas

class TaskController extends Controller {
    public function __construct() {
        $this->middleware('auth');
    }

    public function index() {
        $tareas = Task::where('user_id', auth()->id())->latest()->get();
        return view('tasks.index', compact('tareas'));
    }

    public function store(Request $request) {
        $request->validate([
            'titulo' => 'required|string|max:255',
            'descripcion'=> 'nullable|string',
            'imagen'=> ['nullable', File::image()] // No permite SVG por defecto
        ]);

        $request->mergeIfMissing(['descripcion' => '']);

        $datos = $request->only(['titulo', 'descripcion']);
        if ($request->hasFile('imagen')) {
            $datos['imagen_path'] = $request->file('imagen')->store('imagenes', 'public');
        }

        $datos['user_id'] = Auth::id();

        Task::create($datos);

        return redirect()->route('tasks.index')->with('success', 'Tarea creada.');
    }
}

Explicación:
Demuestra validación avanzada (sin SVG), asignación automática del usuario autenticado y el uso del método mergeIfMissing.

Uso del método nestedWhere()

Ejemplo para filtrar tareas que cumplen múltiples condiciones fácilmente:

$tareasImportantes = Task::nestedWhere(
    'prioridad', '=', 'alta', 'or', 'fecha_limite', '<', now()->addDays(7)
)->get();

Explicación:
Este método facilita hacer consultas complejas más legibles.

Comando para ejecutar tareas concurrentes

class ComputeStats extends Command {
    protected $signature = 'compute:stats';

    public function handle() {
        $resultados = Concurrency::run([
            'conteo_tareas' => fn() => DB::table('tasks')->count(),
            'calculo_matematico' => fn() => array_sum(range(1, 1000000)),
        ]);

        foreach ($resultados as $clave => $valor) {
            $this->info("{$clave}: {$valor}");
        }
    }
}

Explicación:
Ejecuta dos procesos simultáneos y muestra cómo Laravel 12 preserva las claves definidas originalmente.

Ejemplo del nuevo método range() en colecciones

$numeros = Collection::range(1, 10, 2)->all(); // [1,3,5,7,9]

Explicación:
El método range() ahora permite generar rangos con saltos especificados.

Ejemplo de prueba unitaria usando Pest PHP v3

use App\Models\Task;
use App\Models\User;

test('crear tarea genera UUID v7', function () {
    $user = User::factory()->create();
    $this->actingAs($user);

    $this->post('/tasks', ['titulo' => 'Ejemplo']);
    $tarea = Task::first();

    expect($tarea->id)->toBeUuid();
});

Explicación:
Esta prueba verifica que el modelo genera correctamente un UUID v7 al crear nuevas tareas.


Cómo ejecutar el proyecto localmente:

  • Instala dependencias PHP y JavaScript:
composer install
npm install && npm run dev
  • Ejecuta migraciones y vincula almacenamiento:
php artisan migrate
php artisan storage:link
  • Inicia servidor:
php artisan serve
  • Ejecuta el comando concurrente desde consola:
php artisan compute:stats

Hasta aquí llega nuestro ejemplo. Esperamos que al probarlo en vuestras máquinas o dockers hayáis podido ver de cerca las novedades y que lo hayáis pasado bien con la guía de hoy.

Os espero en próximos artículos!

Node.js 22: Novedades y una Kata Inspirada en Talent Arena

0

La reciente versión de Node.js 22 introduce mejoras significativas en rendimiento, seguridad y compatibilidad con las últimas características de JavaScript. A continuación, repasamos algunos de los cambios más relevantes y proponemos una kata inspirada en el Talent Arena que se celebra en Barcelona.

Novedades Principales de Node.js 22

  1. Actualización del Motor V8 a la versión 12.4
    Se han incorporado mejoras en el rendimiento y nuevas funciones como Array.fromAsync, métodos para Set y optimización en la recolección de basura en WebAssembly.
  2. Activación del Compilador Maglev
    Ahora Maglev está habilitado por defecto en sistemas compatibles, mejorando la ejecución de programas de corta duración.
  3. Soporte Experimental para require() en Módulos ES
    Se ha añadido la opción --experimental-require-module para permitir la carga sincrónica de módulos ES, facilitando su integración en proyectos existentes.
  4. Mejoras en Seguridad
    Node.js 22 incorpora actualizaciones en TLS y en la validación de certificados, reforzando la protección frente a ataques.
  5. Optimización del Sistema de Módulos
    Se ha mejorado la compatibilidad y el rendimiento de los módulos ES, lo que facilita el uso de la sintaxis moderna de JavaScript en Node.js.

Kata: Gestión de Sesiones en Talent Arena

Para ilustrar algunas de estas mejoras, esta kata propone simular la gestión de participantes en un evento como Talent Arena, utilizando algunas de las nuevas características de Node.js 22.

Objetivo

Desarrollar una aplicación en Node.js 22 que realice las siguientes funciones:

  1. Registrar Participantes
    Utilizar Array.fromAsync para procesar de manera asíncrona una lista de registros.
  2. Asignar Sesiones
    Implementar un sistema que distribuya participantes en sesiones sin duplicaciones, aprovechando las mejoras en Set.
  3. Notificaciones en Tiempo Real
    Integrar WebSockets para enviar avisos sobre cambios en las sesiones.
  4. Generar Reportes
    Usar iteradores para recorrer la lista de participantes y generar informes.

Consideraciones Técnicas

  • Optimizar la ejecución con el compilador Maglev.
  • Aplicar mejoras de seguridad con TLS actualizado.
  • Utilizar módulos ES para una mejor organización del código.

Esta kata es una oportunidad para explorar las novedades de Node.js 22 en un contexto práctico.

Pasos para Resolver la Kata

1. Configurar el Proyecto

Antes de comenzar, es necesario crear un nuevo proyecto en Node.js. Para ello, se ejecuta el siguiente comando en la terminal:

mkdir talent-arena
cd talent-arena
npm init -y

Es recomendable asegurarse de que la versión instalada de Node.js sea la 22. Se puede verificar con node -v. Si no está actualizada, se puede descargar la última versión desde la página oficial de Node.js.

2. Registrar Participantes

Para procesar los participantes de manera asíncrona, se usa Array.fromAsync(), una función introducida en Node.js 22. El siguiente código simula la obtención de una lista de participantes desde una fuente externa y los convierte en objetos con un campo de fecha de registro.

// participants.js
export async function fetchParticipants() {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve(["Alice", "Bob", "Charlie", "David"]);
        }, 1000);
    });
}

export async function registerParticipants() {
    const participants = await fetchParticipants();
    const processed = await Array.fromAsync(participants, async (participant) => {
        return { name: participant, registeredAt: new Date() };
    });
    return processed;
}

El método fetchParticipants() simula la carga de datos desde un servidor, mientras que Array.fromAsync() permite transformar cada entrada de la lista sin bloquear la ejecución del código.

3. Asignar Sesiones sin Duplicaciones

Para distribuir a los participantes en diferentes sesiones sin riesgo de duplicaciones, se emplea la estructura Set, la cual ha recibido optimizaciones en esta versión de Node.js. A continuación, se muestra cómo organizar a los asistentes en dos sesiones:

// sessions.js
export function assignSessions(participants) {
    const session1 = new Set();
    const session2 = new Set();
    participants.forEach((participant, index) => {
        if (index % 2 === 0) {
            session1.add(participant.name);
        } else {
            session2.add(participant.name);
        }
    });
    return { session1: [...session1], session2: [...session2] };
}

Los participantes se asignan de forma alterna entre las dos sesiones, asegurando que cada uno solo aparezca una vez, sin importar cuántas veces se intente registrarlo.

4. Notificaciones en Tiempo Real con WebSockets

Para informar a los participantes sobre cambios en las sesiones en tiempo real, se implementa un servidor WebSocket utilizando la librería ws. Para ello, primero se instala la dependencia con:

npm install ws

Luego, se configura el servidor WebSocket, permitiendo conexiones de clientes y enviando un mensaje de bienvenida:

// server.js
import { WebSocketServer } from 'ws';

const wss = new WebSocketServer({ port: 8080 });

wss.on('connection', (ws) => {
    console.log('Cliente conectado');
    ws.send(JSON.stringify({ message: "Bienvenido a Talent Arena!" }));

    ws.on('message', (data) => {
        console.log(`Mensaje recibido: ${data}`);
    });

    ws.on('close', () => {
        console.log('Cliente desconectado');
    });
});

console.log("Servidor WebSocket corriendo en ws://localhost:8080");

Este código permite a los clientes recibir notificaciones en tiempo real cuando haya cambios en las sesiones, facilitando la interacción dinámica entre el servidor y los participantes.

5. Generar Reportes Usando Iteradores

Para recorrer la lista de participantes y generar reportes de manera eficiente, se emplean funciones generadoras. A continuación, se presenta una implementación que itera sobre los participantes y devuelve un informe detallado.

// reports.js
export function generateReport(participants) {
    function* reportGenerator() {
        for (const participant of participants) {
            yield `Participante: ${participant.name}, Registrado el: ${participant.registeredAt}`;
        }
    }

    const report = [];
    for (const entry of reportGenerator()) {
        report.push(entry);
    }
    return report;
}

Esta solución permite recorrer la lista de manera controlada, generando los reportes sin necesidad de cargar todos los datos en memoria de una sola vez.

6. Ejecutar Todo el Proyecto

Para poner en funcionamiento todas las funcionalidades desarrolladas, se integra el código en un solo archivo que ejecuta el flujo completo del programa.

import { registerParticipants } from './participants.js';
import { assignSessions } from './sessions.js';
import { generateReport } from './reports.js';

async function main() {
    const participants = await registerParticipants();
    console.log("Participantes Registrados:", participants);

    const sessions = assignSessions(participants);
    console.log("Sesiones Asignadas:", sessions);

    const report = generateReport(participants);
    console.log("Reporte de Participantes:\n", report.join("\n"));
}

main();

Para ejecutar el programa, se debe correr el siguiente comando en la terminal:

node index.js

Para obtener más información sobre ejercicios similares y continuar explorando nuevas soluciones, visita nuestra web.

Nos vemos en Talent Arena: mentoría el 3 y 4 de marzo

0

¡Nos complace anunciar nuestra participación en la primera edición de Talent Arena, el evento europeo líder dedicado al talento digital, que se celebrará del 3 al 5 de marzo de 2025 en el Pabellón 8 de Fira de Barcelona, Montjuïc!

Durante estos tres días, más de 200 expertos compartirán sus conocimientos en áreas clave como inteligencia artificial, ingeniería de software, computación en la nube y ciberseguridad. Destacan ponentes de renombre como Steve Wozniak, cofundador de Apple, y Garry Kasparov, campeón mundial de ajedrez y promotor de la IA.

Nos encontrarás en la Zona de Mentoría los días 3 y 4 de marzo, donde ofreceremos orientación personalizada para ayudarte a avanzar en tu carrera profesional. Este espacio está diseñado para que profesionales de la tecnología puedan asesorarte en tus retos y objetivos, brindándote estrategias y consejos adaptados a tus necesidades.

Además, al registrarte y asistir a Talent Arena, obtendrás un pase gratuito para el 6 de marzo en MWC Barcelona 2025, ampliando aún más tus oportunidades de aprendizaje y networking.

No pierdas esta oportunidad única de conectar con líderes de la industria, ampliar tus conocimientos y dar un impulso a tu trayectoria profesional. ¡Te esperamos en Talent Arena 2025!