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))




python-3.x