Como faço para converter uma variável de string de bytes de Python 3 em uma string regular?

116

Eu li em um anexo de e-mail XML com

bytes_string=part.get_payload(decode=False)

A carga útil vem como uma string de bytes, como meu nome de variável sugere.

Estou tentando usar a abordagem recomendada do Python 3 para transformar essa string em uma string utilizável que eu possa manipular.

O exemplo mostra:

str(b'abc','utf-8')

Como posso aplicar o bargumento de palavra-chave (bytes) à minha variável bytes_stringe usar a abordagem recomendada?

O jeito que tentei não funciona:

str(bbytes_string, 'utf-8')
DjangoTango
fonte

Respostas:

210

Você acertou quase na última linha. Você quer

str(bytes_string, 'utf-8')

porque o tipo de bytes_stringé byteso mesmo que o tipo de b'abc'.

Toby Speight
fonte
6
str(bytes_string, 'utf-8', 'ignore')Os erros podem ser ignorados passando o terceiro parâmetro.
Shubhamoy
2
Parece que deve ser um comentário à resposta de pylang (que aborda o tratamento de entrada inválida). Se (você acredita que) não há nada de errado bytes_string, por que deseja ignorar os erros?
Toby Speight
3
Estou recebendo o seguinte erro com sua abordagem: UnicodeDecodeError: 'utf-8' codec can't decode byte 0xbf in position 0: invalid start bytepara os seguintes bytes string b'\xbf\x8cd\xba\x7f\xe0\xf0\xb8t\xfe.TaFJ\xad\x100\x07p\xa0\x1f90\xb7P\x8eP\x90\x06)0'@TobySpeight
alper
Bem, @alper, essa não é uma string UTF-8 válida, então o que você esperava?
Toby Speight
Obrigado pela solução
Ajay Kumar,
49

Chame decode()uma bytesinstância para obter o texto que ela codifica.

str = bytes.decode()
uname01
fonte
5
UnicodeDecodeError: o codec 'utf-8' não pode decodificar o byte 0xf6 na posição 230: byte inicial inválido
Juha Untinen
3
@JuhaUntinen sua codificação provavelmente não é utf-8.
tommy.carstensen
4
Como filtrar (pular) caracteres não UTF8 da matriz?
Dr. Failov
9

ATUALIZADA:

NÃO TER NENHUMA be aspas no primeiro e no final

Como converter bytescomo visto em strings, mesmo em situações estranhas.

Como seu código pode ter caracteres irreconhecíveis para 'utf-8'codificação, é melhor usar apenas str sem quaisquer parâmetros adicionais:

some_bad_bytes = b'\x02-\xdfI#)'
text = str( some_bad_bytes )[2:-1]

print(text)
Output: \x02-\xdfI

se você adicionar 'utf-8'parâmetro, a esses bytes específicos, deve receber um erro.

Como diz o padrão PYTHON 3, agora textestaria no utf-8 sem preocupação.

Seyfi
fonte
o resultado é "b '\\ x02 - \\ xdfI #)'", que provavelmente não é o que ele deseja
Glen Thompson,
@GlenThompson é apenas um exemplo para condições indesejáveis, que podem acontecer. Eu uso este texto específico intencionalmente. Se você quer dizer que o texto tem um bprimeiro, atualizei a resposta
Seyfi
muito obrigado, estou procurando uma maneira de remover o b '' de uma string que tem o caractere ansi sem codificar e perder os caracteres, eu sou novo em python e não sei se posso reduzir um array desde o início e começando a usar índices: O
Diego Fernando Murillo Valenci
@DiegoFernandoMurilloValenci, de nada. Fico feliz em poder ajudar.
Seyfi 01 de
6

Como filtrar (pular) caracteres não UTF8 da matriz?

Para abordar este comentário na postagem de @ uname01 e no OP, ignore os erros:

Código

>>> b'\x80abc'.decode("utf-8", errors="ignore")
'abc'

Detalhes

Nos documentos , aqui estão mais exemplos usando o mesmo errorsparâmetro:

>>> b'\x80abc'.decode("utf-8", "replace")
'\ufffdabc'
>>> b'\x80abc'.decode("utf-8", "backslashreplace")
'\\x80abc'
>>> b'\x80abc'.decode("utf-8", "strict")  
Traceback (most recent call last):
    ...
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x80 in position 0:
  invalid start byte

O argumento de erros especifica a resposta quando a string de entrada não pode ser convertida de acordo com as regras de codificação. Os valores legais para este argumento são 'strict'(levantar uma UnicodeDecodeErrorexceção), 'replace'(usar U+FFFD, REPLACEMENT CHARACTER) ou 'ignore'(apenas deixar o caractere de fora do resultado Unicode).

pilang
fonte