bytearray.resize: redimensiona buffers con seguridad

Publicado el: 24/10/2026
Tempo de leitura: 5 minutos
Código binario que representa bytearray.resize en Python

bytearray.resize() cambia directamente la longitud de un búfer mutable de bytes. Resulta útil cuando una aplicación necesita reservar espacio, reducir datos ya procesados, crear registros de tamaño fijo o adaptar paquetes binarios sin construir manualmente otro bytearray. Su uso correcto requiere atención a las vistas de memoria, el relleno con ceros, los tamaños no confiables, el rendimiento y la compatibilidad.

Qué representa bytearray

Un bytearray almacena una secuencia mutable de bytes. A diferencia de bytes, permite modificar elementos y segmentos. Por eso es apropiado para búferes de red, formatos de archivo, parsers incrementales e integración con APIs nativas. Para repasar conceptos relacionados, consulta las guías de Academify sobre tipos de datos, archivos grandes, archivos en Python y módulo os.

Comportamiento básico

Cuando el tamaño solicitado es mayor que la longitud actual, resize() amplía el objeto y rellena la zona nueva con bytes cero. Cuando es menor, elimina los bytes finales. La modificación ocurre sobre el mismo objeto, por lo que todas las referencias observan la nueva longitud.

datos = bytearray(b"ABC")
datos.resize(6)
print(datos)  # bytearray(b'ABC\x00\x00\x00')

datos.resize(2)
print(datos)  # bytearray(b'AB')

El método devuelve None, como otras operaciones mutables de Python.

Ampliar un búfer

El relleno automático con ceros facilita la reserva de espacio, pero esos ceros no son necesariamente datos válidos. En un protocolo o archivo binario pueden tener un significado concreto. Antes de guardar o transmitir el búfer, escribe todos los campos esperados.

cabecera = bytearray(b"PKT")
cabecera.resize(8)
cabecera[3:7] = (1250).to_bytes(4, "big")
cabecera[7] = 1

Esta técnica deja explícito el tamaño final y evita concatenaciones sucesivas.

Reducir sin perder datos importantes

Reducir el tamaño descarta definitivamente los bytes situados después del nuevo límite. Verifica que ya hayan sido procesados o copiados. En un parser incremental es habitual consumir un mensaje y conservar solamente el resto.

buffer = bytearray(b"MSG1RESTO")
consumidos = 4
del buffer[:consumidos]

La eliminación por segmento ya ajusta la longitud. resize() es más útil cuando se conoce directamente el tamaño objetivo.

Validar tamaños

El tamaño debe ser un entero no negativo. Además, una entrada externa nunca debe controlar una asignación ilimitada. Un archivo o paquete malicioso puede declarar una longitud enorme y agotar la memoria.

MAX_BUFFER = 8 * 1024 * 1024

def resize_seguro(buf: bytearray, tamano: int) -> None:
    if not isinstance(tamano, int):
        raise TypeError("el tamaño debe ser entero")
    if not 0 <= tamano <= MAX_BUFFER:
        raise ValueError("tamaño fuera del límite")
    buf.resize(tamano)

En servidores, combina esta regla con timeouts, cuotas por cliente y límites globales de memoria.

memoryview y búferes exportados

Existe un caso importante cuando un memoryview activo apunta al mismo objeto. Python puede impedir el redimensionamiento mientras el búfer está exportado, porque una reasignación podría invalidar la vista.

datos = bytearray(b"abcdef")
vista = memoryview(datos)
try:
    # datos.resize(20) puede fallar aquí
    pass
finally:
    vista.release()

datos.resize(20)

Mantén corta la vida de las vistas y libéralas antes de cambiar la longitud. Esto es esencial con bibliotecas nativas, NumPy y APIs sin copia.

resize, extend y segmentos

extend() añade bytes conocidos. resize() establece una longitud objetivo y rellena con ceros. La asignación por segmentos reemplaza una región y también puede alterar la longitud.

buf = bytearray(b"AB")
buf.extend(b"CD")
buf.resize(8)
buf[4:] = b"1234"

Usa extend() si ya tienes el contenido; segmentos para reemplazar posiciones concretas; y resize() cuando el requisito principal es el tamaño final.

Paquetes de red

Un cliente de red puede leer una cabecera con la longitud del payload, validarla, ampliar el búfer y rellenarlo a medida que llegan los fragmentos.

def preparar_paquete(prefijo: bytes, payload_size: int) -> bytearray:
    limite = 1_000_000
    if not 0 <= payload_size <= limite:
        raise ValueError("payload inválido")
    paquete = bytearray(prefijo)
    paquete.resize(len(prefijo) + payload_size)
    return paquete

No supongas que una sola lectura completa toda la región. Registra cuántos bytes llegaron y trata cierres prematuros.

Registros binarios de ancho fijo

El método ayuda a crear campos de tamaño fijo. Un texto puede codificarse, truncarse cuando sea necesario y rellenarse con ceros.

def campo_fijo(texto: str, tamano: int) -> bytes:
    buf = bytearray(texto.encode("utf-8"))
    if len(buf) > tamano:
        del buf[tamano:]
    else:
        buf.resize(tamano)
    return bytes(buf)

Evita cortar un carácter UTF-8 multibyte por la mitad. Define una política por caracteres o valida la decodificación después del corte.

Rendimiento

Redimensionar puede requerir reasignación y copia interna. Evita aumentar y reducir repetidamente en cantidades pequeñas dentro de bucles intensivos. Calcula el tamaño final cuando sea posible o crece por bloques. Mide el caso real con herramientas como timeit.

No asumas que resize() siempre será más rápido que concatenar, usar extend() o realizar una única asignación final.

Compatibilidad entre versiones

El proyecto debe declarar la versión mínima de Python. En intérpretes anteriores, la reducción puede implementarse con eliminación de segmentos y la ampliación con bytes cero.

def resize_compatible(buf: bytearray, tamano: int) -> None:
    metodo = getattr(buf, "resize", None)
    if metodo is not None:
        metodo(tamano)
    elif tamano < len(buf):
        del buf[tamano:]
    else:
        buf.extend(b"\x00" * (tamano - len(buf)))

Manejo de errores

Distingue una entrada inválida de un fallo de asignación o un conflicto con una vista activa. Capturar todas las excepciones oculta la causa. Atrapa solamente los errores que la aplicación pueda tratar y conserva la excepción original.

def reservar(buf: bytearray, tamano: int) -> None:
    try:
        resize_seguro(buf, tamano)
    except (TypeError, ValueError) as exc:
        raise ValueError(f"solicitud inválida: {tamano}") from exc

Pruebas recomendadas

Comprueba ampliación, reducción, tamaño cero, tamaño sin cambios, valores negativos, límite máximo, conservación del prefijo y relleno con ceros. Incluye una prueba con memoryview activa para documentar el comportamiento esperado.

def test_ampliacion():
    b = bytearray(b"xy")
    b.resize(5)
    assert b == bytearray(b"xy\x00\x00\x00")

def test_reduccion():
    b = bytearray(b"abcdef")
    b.resize(3)
    assert b == bytearray(b"abc")

Seguridad

Reducir un búfer no equivale a borrar de forma garantizada la memoria física. Los secretos requieren mecanismos específicos. También debes limitar tamaños externos y validar operaciones como longitud de cabecera más longitud de contenido.

Buenas prácticas

Valida antes de asignar, documenta el significado del relleno, libera vistas, evita redimensionamientos repetitivos, prueba los límites y convierte el resultado a bytes cuando deba quedar inmutable. Mantén la descripción del formato binario cerca de sus validaciones.

Conclusión

bytearray.resize() expresa claramente la operación de cambiar la longitud de un búfer mutable. Simplifica paquetes, registros fijos y procesamiento binario si se utiliza con límites y pruebas. Consulta la documentación oficial de bytearray y del protocolo de búfer para detalles autoritativos.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Contenido del artículo

    Artículos relacionados

    Código Python en un portátil para filtrar valores None
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    operator.is_none: filtra None sin perder falsy

    Aprende operator.is_none e is_not_none para filtrar None sin eliminar valores falsy válidos en Python.

    Ler mais

    Tempo de leitura: 4 minutos
    23/10/2026
    Código Python en un portátil para crear dataclasses dinámicas
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    make_dataclass decorator: transforma dataclasses

    Aprende a usar el parámetro decorator de make_dataclass para validar, registrar y transformar dataclasses dinámicas en Python.

    Ler mais

    Tempo de leitura: 6 minutos
    23/10/2026
    Estructura de código y XML para canonicalización con Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    ElementTree canonicalize: normaliza XML en Python

    Aprende ElementTree canonicalize en Python para comparar XML, generar hashes estables y controlar namespaces, espacios y comentarios.

    Ler mais

    Tempo de leitura: 5 minutos
    22/10/2026
    Código Python en una pantalla
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    T-strings y templatelib: interpolación estructurada

    Aprende t-strings y string.templatelib en Python para interpolación estructurada, renderizado seguro, logs y procesamiento personalizado.

    Ler mais

    Tempo de leitura: 6 minutos
    22/10/2026
    Base SQLite y código Python para exportación selectiva con iterdump
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    SQLite iterdump: crea dumps selectivos en Python

    Aprende sqlite3.Connection.iterdump con filtro para crear dumps SQLite selectivos, validar dependencias y restaurar con seguridad.

    Ler mais

    Tempo de leitura: 4 minutos
    21/10/2026
    Código y archivos que representan compresión de datos con Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    compression.zstd: Zstandard rápido en Python

    Aprende compression.zstd en Python para comprimir archivos y datos con velocidad, streaming, integridad y seguridad.

    Ler mais

    Tempo de leitura: 7 minutos
    21/10/2026