HOWTO · Python
Arreglar el error Bytes-Like Object Is Required Not STR en Python
Este tutorial analiza el objeto similar a bytes, no se requiere un error str en Python.
En esta página
El TypeError de Python «a bytes-like object is required, not ‘str’» significa que una operación espera bytes, pero recibió texto (str). Comprueba el valor en la llamada que falla y haz que la operación coincida con los datos: codifica el texto cuando una API necesite bytes o decodifica los bytes cuando necesites procesar texto.
Cómo entender el TypeError “bytes-like object is required, not ‘str’”
El mensaje indica los dos lados de la incompatibilidad. «Bytes-like object is required» describe el valor que acepta la operación; «not ‘str’» señala que el valor proporcionado era texto. El error suele aparecer en una operación con delimitadores, al escribir en un archivo binario o al enviar datos por un socket. Localiza esa llamada concreta y sigue el argumento hasta el punto donde se leyó, creó o convirtió.
Por qué no coinciden el texto y los datos binarios
En Python 3, str es texto: una secuencia de caracteres Unicode. bytes es una secuencia inmutable de valores de bytes, que suele utilizarse para texto codificado, archivos y datos de red. Son tipos distintos y no son intercambiables, aunque los bytes representen caracteres legibles.
La codificación transforma texto en bytes mediante una codificación de caracteres, como UTF-8. La decodificación interpreta bytes como texto usando la codificación correspondiente. La elección depende del significado de los datos y del tipo que acepte la API receptora; convertir a ciegas puede ocultar la incompatibilidad o corromper los datos. Las convenciones de cadenas de Python 2 eran distintas, así que no conviene usarlas para razonar sobre código de Python 3.
Convierte texto y bytes en el límite entre ambos
Usa encode() con texto cuando pases a una API que requiera bytes. Usa decode() con bytes cuando pases a procesar texto y elige la codificación que corresponda a cómo se produjeron esos bytes.
La transformación es explícita, así que el código muestra dónde el texto se convierte en bytes y dónde esos bytes vuelven a convertirse en texto. UTF-8 es una opción habitual para el texto que se debe almacenar o enviar en un formato portátil. Conserva el valor original en su forma inicial hasta saber qué acepta la siguiente operación; así será más fácil localizar una incompatibilidad y evitar tratar contenido binario como si fuera texto.
Ejecuta este ejemplo:
El código y las etiquetas o salidas visibles de esta sección se mantienen en inglés.
text = "Hello, World!"
data = text.encode("utf-8")
print(data)
print(data.decode("utf-8"))
b'Hello, World!'
Hello, World!
El prefijo b de la primera línea de salida indica un valor bytes. Llamar a str(data) no revierte la codificación: no decodifica el contenido de los bytes y puede mostrar una representación como b'Hello, World!'. Usa data.decode("utf-8") cuando los bytes contengan texto UTF-8 y la siguiente operación necesite un str.
Corrige el error en el código de archivos y sockets
Un archivo abierto en modo binario devuelve o acepta bytes; el modo de texto se encarga de decodificar o codificar por ti. Si el contenido es binario, conserva el valor como bytes y usa un delimitador de bytes, como en parts = data.split(b","). Si el archivo contiene texto UTF-8 y necesitas operar con texto, decodifícalo primero y usa un delimitador de texto: parts = data.decode("utf-8").split(","). No conviertas con str() una lectura de bytes esperando que así se decodifique el archivo.
El mismo límite entre tipos se aplica a los métodos de socket orientados a bytes. sock.sendall(b"hello") pasa bytes directamente. Si el mensaje empieza como texto, codifícalo de forma explícita, por ejemplo, con sock.sendall(message.encode("utf-8")). Esto describe el tipo del argumento; un intercambio real por socket también depende de que el socket esté conectado y del protocolo del otro extremo.
Comprueba el valor antes de elegir una conversión
En la operación que falla, inspecciona type(value) o usa isinstance(value, bytes) e isinstance(value, str). Después, comprueba qué tipo espera la API, decide si el valor representa texto o datos binarios arbitrarios y conviértelo una sola vez en ese límite. Para texto, elige la codificación que use el archivo o el protocolo; para datos binarios arbitrarios, conserva los bytes y cambia el delimitador o la operación para que acepte bytes. Así se resuelve la incompatibilidad de tipos sin adivinar por el aspecto que tiene el valor al imprimirlo.