Curso
Uma das sequências internas menos conhecidas do Python é a de bytes, que é uma sequência imutável de números inteiros. Cada número inteiro representa um byte de dados. Os dados geralmente são transmitidos em redes e programas como bytes. Os bytes não são legíveis por humanos, e muitas vezes precisamos convertê-los em strings em nossos programas Python.
Este tutorial explora as técnicas de conversão de bytes em strings em Python. Se você estiver interessado na operação inversa, confira meu tutorial sobre como converter strings em bytes em Python.
Vamos começar com uma resposta curta para aqueles de vocês que estão com pressa.
Resposta curta: Como converter bytes em strings em Python
A principal ferramenta para converter bytes em strings em Python é o método .decode()
:
data = b"\xc3\xa9clair"
text = data.decode(encoding="utf-8")
print(text)
éclair
O método .decode()
retorna uma cadeia de caracteres que representa o objeto bytes
. Neste exemplo, a decodificação UTF-8 é usada. UTF-8 é a codificação padrão, portanto não é necessária no exemplo acima, mas também podemos usar outras codificações.
Entendendo bytes e strings em Python
O Python tem uma estrutura de dados integrada bytes
, que é uma sequência imutável de números inteiros no intervalo de 0 a 255. Um número inteiro dentro desse intervalo de 256 números pode ser representado usando oito bits de dados, o que equivale a um byte. Portanto, cada elemento em um objeto bytes
é um número inteiro que representa um byte.
Vamos usar o construtor bytes()
para criar um objeto bytes
a partir de uma lista:
data = bytes([68, 97, 116, 97, 67, 97, 109, 112])
print(type(data))
<class 'bytes'>
Essa sequência de números inteiros é imutável:
data[0] = 100
Traceback (most recent call last):
...
data[0] = 100
~~~~^^^
TypeError: 'bytes' object does not support item assignment
O Python levanta um TypeError
quando você tenta alterar um valor dentro dessa sequência. Vamos confirmar que um objeto bytes
só pode conter números inteiros no intervalo de 0 a 255:
data = bytes([254, 255, 256])
Traceback (most recent call last):
...
data = bytes([254, 255, 256])
^^^^^^^^^^^^^^^^^^^^^^
ValueError: bytes must be in range(0, 256)
O site ValueError
afirma que um número inteiro que representa um byte deve ser um membro do site range(0, 256)
. O final do intervalo é excluído, como é a convenção com um intervalo de números em Python.
Podemos exibir o objeto bytes usando print()
:
data = bytes([68, 97, 116, 97, 67, 97, 109, 112])
print(data)
b'DataCamp'
A representação mostra o objeto bytes
representado por caracteres. O Python exibe os inteiros usando os caracteres ASCII correspondentes a esses valores. O prefixo b antes dos caracteres entre aspas mostra que esse é um objeto bytes
.
Também podemos criar um objeto bytes
usando diretamente o literal de bytes:
data = b"DataCamp"
print(data)
print(data[0])
b'DataCamp'
68
O objeto é exibido usando caracteres, mas seus elementos são números inteiros.
No entanto, os objetos bytes
só são legíveis por humanos quando você usa números inteiros correspondentes a caracteres ASCII imprimíveis. Como o ASCII é uma codificação de 7 bits, ele contém 128 códigos, mas somente 95 desses caracteres ASCII podem ser impressos.
Os números inteiros entre 0 e 127 que não têm um caractere ASCII imprimível e os números inteiros entre 128 e 255 são exibidos como números hexadecimais:
data = bytes([0, 68, 97, 116, 97, 67, 97, 109, 112, 200])
print(data)
b'\x00DataCamp\xc8'
O primeiro número inteiro da lista agora é 0, que não é um caractere imprimível em ASCII. O objeto bytes
exibe esse número inteiro como \x00
, a representação hexadecimal de 0. O número inteiro final é 200, que está fora do intervalo ASCII, mas dentro do intervalo de números inteiros que podem ser usados em bytes. O Python exibe esse número inteiro como \xc8
, que é 200 em hexadecimal.
As estruturas de dados bytes
e strings compartilham recursos comuns. Ambas são sequências imutáveis, mas bytes
contém números inteiros, enquanto as cadeias de caracteres contêm caracteres:
data = bytes([68, 97, 116, 97, 67, 97, 109, 112])
print(data[0])
text = "DataCamp"
print(text[0])
68
D
Os bytes são usados para transferir dados em redes e entre diferentes interfaces. A próxima seção deste artigo explora como converter bytes em cadeias de caracteres.
Conversão de bytes em cadeias de caracteres: Os .decode()
Método
Um objeto bytes
em Python é legível para humanos somente quando contém caracteres ASCII legíveis. Na maioria dos aplicativos, esses caracteres não são suficientes. Podemos converter um objeto bytes
em uma string usando o método .decode()
:
data = bytes([68, 97, 116, 97, 67, 97, 109, 112])
text = data.decode()
print(text)
print(type(text))
DataCamp
<class 'str'>
No entanto, existem codificações diferentes para converter entre bytes e cadeias de caracteres. Os números inteiros no exemplo acima representam caracteres ASCII imprimíveis. No entanto, a codificação padrão usada quando nenhum argumento é passado para .decode()
é UTF-8 e não ASCII. UTF-8 é a codificação mais amplamente usada para caracteres Unicode.
Os primeiros 128 códigos UTF-8 correspondem aos códigos ASCII, e é por isso que os dados do objeto bytes são decodificados para a string "DataCamp"
no exemplo acima.
No entanto, o Unicode contém quase 150.000 caracteres. O UTF-8 codifica todos os caracteres não ASCII em Unicode usando dois ou mais bytes.
Vamos criar um novo objeto bytes
e decodificá-lo:
data = bytes([195, 169])
print(data)
text = data.decode()
print(text)
b'\xc3\xa9'
é
O objeto bytes
contém dois bytes: os números inteiros 195 e 169. O Python exibe a representação hexadecimal desses bytes. No entanto, .decode()
retorna uma string decodificando o objeto bytes
usando a codificação UTF-8. O par de bytes b'\xc3\xa9'
representa a letra e com um acento agudo, é.
O método .decode()
recebe um argumento opcional para especificar a codificação:
text = data.decode("utf-8")
print(text)
é
UTF-8 é a codificação padrão, mas outras codificações podem ser usadas. Também podemos converter uma string em um objeto bytes
usando o método de string .encode()
com várias codificações:
text = "éclair"
data = text.encode("utf-8")
print(data)
data = text.encode("utf-16")
print(data)
b'\xc3\xa9clair'
b'\xff\xfe\xe9\x00c\x00l\x00a\x00i\x00r\x00'
A mesma cadeia de caracteres é convertida em diferentes objetos bytes
, dependendo da codificação de caracteres que usamos.
Erros de codificação
A escolha de codificações de caracteres pode levar a erros se uma codificação diferente for usada na conversão entre bytes e cadeias de caracteres. Vamos usar o exemplo com a string "éclair"
codificada em bytes usando a codificação UTF-8:
text = "éclair"
data = text.encode("utf-8")
print(data)
b'\xc3\xa9clair'
Essa sequência de bytes representa caracteres usando a codificação UTF-8. O método .decode()
gera um erro se você usar a codificação errada:
text = data.decode("ascii")
print(text)
Traceback (most recent call last):
...
text = data.decode("ascii")
^^^^^^^^^^^^^^^^^^^^
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)
No entanto, podemos incluir o argumento opcional errors
para lidar com quaisquer erros. O valor padrão do parâmetro errors
é "strict"
, que gera um erro para caracteres inválidos.
O método .decode()
pode ser chamado com errors="ignore"
para que você ignore todos os caracteres inválidos:
text = data.decode("ascii", errors="ignore")
print(text)
clair
O primeiro caractere da cadeia original é é, que não é um caractere ASCII. Portanto, .decode()
retorna uma cadeia de caracteres sem o primeiro caractere.
Outra opção é chamar .decode()
com errors="replace"
, que substitui bytes inválidos por �:
text = data.decode("ascii", errors="replace")
print(text)
��clair
Essa saída mostra que estão faltando caracteres na string. A escolha do tratamento de erros depende do aplicativo.
Conversão de bytes em cadeias de caracteres com str()
O método .decode()
é a principal rota para converter bytes em strings. No entanto, também é possível usar o construtor str()
diretamente. Usando o construtor str()
em um objeto bytes
, você criará uma representação de string dos bytes brutos:
data = b'\xc3\xa9clair'
text = str(data)
print(text)
print(type(text))
b'\xc3\xa9clair'
<class 'str'>
No entanto, o construtor str()
também aceita um argumento encoding
, que pode ser usado para criar uma cadeia de caracteres com base em uma codificação específica:
text = str(data, encoding='utf-8')
print(text)
éclair
Conversão de bytes em cadeias de caracteres com codecs.decode()
O módulo codecs
da biblioteca padrão do Python fornece a interface para codificação e decodificação de dados. Esse módulo também fornece uma função .decode()
que pode ser usada para converter bytes Python em strings:
import codecs
data = b'\xc3\xa9clair'
text = codecs.decode(data, encoding='utf-8')
print(text)
éclair
Essas técnicas alternativas de conversão não são métodos do tipo bytes
, mas funções que exigem que o objeto bytes
seja passado como argumento.
Conclusão
Os dados são frequentemente transferidos como bytes, e muitos aplicativos Python precisam converter entre bytes e strings. Um objeto bytes
é uma sequência imutável de bytes que pode ser convertida em um string
usando uma das várias codificações de caracteres.
A principal rota para converter bytes Python em uma string é o método .decode()
, que permite aos usuários escolher uma codificação e uma estratégia de tratamento de erros.
Você pode continuar seu aprendizado de Python com os seguintes tutoriais e cursos: