python3 - python transform byte to string
Converter bytes em uma string? (11)
Ao trabalhar com dados de sistemas Windows (com \r\n
finais de linha), minha resposta é
String = Bytes.decode("utf-8").replace("\r\n", "\n")
Por quê? Tente isso com um Input.txt de múltiplas linhas:
Bytes = open("Input.txt", "rb").read()
String = Bytes.decode("utf-8")
open("Output.txt", "w").write(String)
Todos os finais de linha serão duplicados (para \r\r\n
), levando a linhas vazias extras. As funções de leitura de texto do Python normalmente normalizam os finais de linha, de forma que as strings usam apenas \n
. Se você receber dados binários de um sistema Windows, o Python não terá chance de fazer isso. Portanto,
Bytes = open("Input.txt", "rb").read()
String = Bytes.decode("utf-8").replace("\r\n", "\n")
open("Output.txt", "w").write(String)
replicará seu arquivo original.
Eu estou usando este código para obter saída padrão de um programa externo:
>>> from subprocess import *
>>> command_stdout = Popen(['ls', '-l'], stdout=PIPE).communicate()[0]
O método comunic () retorna uma matriz de bytes:
>>> command_stdout
b'total 0\n-rw-rw-r-- 1 thomas thomas 0 Mar 3 07:03 file1\n-rw-rw-r-- 1 thomas thomas 0 Mar 3 07:03 file2\n'
No entanto, gostaria de trabalhar com a saída como uma string normal do Python. Para que eu pudesse imprimir assim:
>>> print(command_stdout)
-rw-rw-r-- 1 thomas thomas 0 Mar 3 07:03 file1
-rw-rw-r-- 1 thomas thomas 0 Mar 3 07:03 file2
Eu acho que é para isso que binascii.b2a_qp() o método binascii.b2a_qp() , mas quando eu tentei obtive o mesmo array de bytes novamente:
>>> binascii.b2a_qp(command_stdout)
b'total 0\n-rw-rw-r-- 1 thomas thomas 0 Mar 3 07:03 file1\n-rw-rw-r-- 1 thomas thomas 0 Mar 3 07:03 file2\n'
Alguém sabe como converter o valor de bytes de volta para string? Quero dizer, usando as "baterias" em vez de fazê-lo manualmente. E eu gostaria que ficasse bem com o Python 3.
Como essa pergunta está realmente perguntando sobre a saída do subprocess
, você tem uma abordagem mais direta disponível, pois o Popen
aceita uma palavra-chave de encoding (no Python 3.6+):
>>> from subprocess import Popen, PIPE
>>> text = Popen(['ls', '-l'], stdout=PIPE, encoding='utf-8').communicate()[0]
>>> type(text)
str
>>> print(text)
total 0
-rw-r--r-- 1 wim badger 0 May 31 12:45 some_file.txt
A resposta geral para outros usuários é decodificar bytes em texto:
>>> b'abcde'.decode()
'abcde'
Sem argumento, sys.getdefaultencoding()
será usado. Se seus dados não são sys.getdefaultencoding()
, você deve especificar a codificação explicitamente na chamada de decode
:
>>> b'caf\xe9'.decode('cp1250')
'café'
Definir universal_newlines para True, ou seja
command_stdout = Popen(['ls', '-l'], stdout=PIPE, universal_newlines=True).communicate()[0]
Enquanto a resposta de @Aaron Maenpaa simplesmente funciona, um usuário perguntou recentemente
Existe alguma maneira mais simples? 'fhand.read (). decode ("ASCII")' [...] É tão longo!
Você pode usar
command_stdout.decode()
decode()
tem um argumento padrão
codecs.decode(obj, encoding='utf-8', errors='strict')
Eu acho que o que você realmente quer é isso:
>>> from subprocess import *
>>> command_stdout = Popen(['ls', '-l'], stdout=PIPE).communicate()[0]
>>> command_text = command_stdout.decode(encoding='windows-1252')
A resposta de Aaron estava correta, exceto que você precisa saber QUAL codificação usar. E eu acredito que o Windows usa 'windows-1252'. Só terá importância se você tiver alguns caracteres incomuns (não-ascii) em seu conteúdo, mas isso fará diferença.
A propósito, o fato de que isso importa é o motivo pelo qual o Python passou a usar dois tipos diferentes de dados binários e de texto: ele não pode converter magicamente entre eles porque não sabe a codificação, a menos que você o informe! A única maneira que você sabe é ler a documentação do Windows (ou lê-lo aqui).
Eu fiz uma função para limpar uma lista
def cleanLists(self, lista):
lista = [x.strip() for x in lista]
lista = [x.replace('\n', '') for x in lista]
lista = [x.replace('\b', '') for x in lista]
lista = [x.encode('utf8') for x in lista]
lista = [x.decode('utf8') for x in lista]
return lista
Para o Python 3, essa é uma abordagem Python muito mais segura para converter de byte
para string
:
def byte_to_str(bytes_or_str):
if isinstance(bytes_or_str, bytes): #check if its in bytes
print(bytes_or_str.decode('utf-8'))
else:
print("Object not of byte type")
byte_to_str(b'total 0\n-rw-rw-r-- 1 thomas thomas 0 Mar 3 07:03 file1\n-rw-rw-r-- 1 thomas thomas 0 Mar 3 07:03 file2\n')
Saída:
total 0
-rw-rw-r-- 1 thomas thomas 0 Mar 3 07:03 file1
-rw-rw-r-- 1 thomas thomas 0 Mar 3 07:03 file2
Se você deve obter o seguinte, tentando decode()
:
AttributeError: 'str' object has no attribute 'decode'
Você também pode especificar o tipo de codificação diretamente em um modelo:
>>> my_byte_str
b'Hello World'
>>> str(my_byte_str, 'utf-8')
'Hello World'
Você precisa decodificar a string de bytes e transformá-la em uma string de caracteres (unicode).
b'hello'.decode(encoding)
ou
str(b'hello', encoding)
Você precisa decodificar o objeto de bytes para produzir uma string:
>>> b"abcde"
b'abcde'
# utf-8 is used here because it is a very common encoding, but you
# need to use the encoding your data is actually in.
>>> b"abcde".decode("utf-8")
'abcde'
def toString(string):
try:
return v.decode("utf-8")
except ValueError:
return string
b = b'97.080.500'
s = '97.080.500'
print(toString(b))
print(toString(s))