[python] 바이트를 문자열로 변환 하시겠습니까?


Answers

나는이 방법이 쉽다라고 생각한다 :

bytes = [112, 52, 52]
"".join(map(chr, bytes))
>> p44
Question

이 코드를 사용하여 외부 프로그램에서 표준 출력을 얻습니다.

>>> from subprocess import *
>>> command_stdout = Popen(['ls', '-l'], stdout=PIPE).communicate()[0]

communicate () 메소드는 바이트 배열을 반환합니다.

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

그러나 출력을 일반적인 파이썬 문자열로 작업하고 싶습니다. 그래서 다음과 같이 인쇄 할 수 있습니다.

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

나는 binascii.b2a_qp() 메소드가 그것을위한 것이라고 생각했지만, 그것을 시도했을 때 같은 바이트 배열을 다시 얻었다 :

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

누구든지 바이트 값을 다시 문자열로 변환하는 방법을 알고 있습니까? 내 말은, 수동으로하는 대신 "배터리"를 사용하는 것입니다. 그리고 파이썬 3에서도 괜찮 으면 좋겠다.




목록 정리 기능을 만들었습니다.

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



http://docs.python.org/3/library/sys.html ,

표준 스트림에서 /로 이진 데이터를 쓰거나 읽으려면 기본 이진 버퍼를 사용하십시오. 예를 들어, stdout에 바이트를 쓰려면 sys.stdout.buffer.write (b'abc ')를 사용하십시오.




파이썬 3에서 직접 사용할 수 있습니다 :

b'hello'.decode()

이는

b'hello'.decode(encoding="utf-8")

여기에서 기본 인코딩은 "utf-8"이거나 다음을 통해 확인할 수 있습니다.

>> import sys
>> sys.getdefaultencoding()



@Aaron Maenpaa의 답변 이 작동하는 동안 사용자가 최근에 물었습니다.

더 이상 간단한 방법이 있습니까? 'fhand.read (). decode ( "ASCII")'[...] 너무 길어!

당신이 사용할 수있는

command_stdout.decode()

decode() 에는 표준 인수가 있습니다.

codecs.decode(obj, encoding='utf-8', errors='strict')




인코딩을 모르는 경우 Python 3 및 Python 2 호환 방법으로 문자열에 이진 입력을 읽으려면 고대 MS-DOS cp437 인코딩을 사용하십시오.

PY3K = sys.version_info >= (3, 0)

lines = []
for line in stream:
    if not PY3K:
        lines.append(line)
    else:
        lines.append(line.decode('cp437'))

인코딩을 알 수 없으므로 영어 이외의 기호가 cp437 문자로 변환됩니다 (영어 문자는 대부분의 단일 바이트 인코딩 및 UTF-8과 일치하기 때문에 번역되지 않습니다).

UTF-8에 대한 임의의 바이너리 입력을 디코딩하는 것은 안전하지 않습니다.

>>> b'\x00\x01\xffsd'.decode('utf-8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 2: invalid
start byte

Python 2의 경우 인기가있는 latin-1 (기본값?)에도 동일하게 적용됩니다. Codepage Layout 의 누락 된 점을 참조하십시오. ordinal not in range 악명 높은 ordinal not in range 로 파이썬이 질식하는 곳입니다.

업데이트 20150604 : Python 3에는 데이터 손실 및 충돌없이 바이너리 데이터로 인코딩하는 surrogateescape 오류 전략이 있지만 성능 및 안정성을 검증하기 위해 [binary] -> [str] -> [binary] 변환 테스트가 필요하다는 소문이 있습니다.

업데이트 20170116 : Nearoo 님의 의견 감사 - backslashreplace 오류 처리기를 사용하여 알 수없는 모든 바이트를 backslashreplace 할 수 있습니다. 이것은 파이썬 3에서만 작동합니다. 따라서이 해결 방법을 사용하더라도 다른 파이썬 버전에서 일관성없는 결과를 얻을 수 있습니다 :

PY3K = sys.version_info >= (3, 0)

lines = []
for line in stream:
    if not PY3K:
        lines.append(line)
    else:
        lines.append(line.decode('utf-8', 'backslashreplace'))

자세한 내용은 https://docs.python.org/3/howto/unicode.html#python-s-unicode-support 를 참조하십시오.

업데이트 20170119 : 파이썬 2와 파이썬 3 모두에서 작동하는 슬래시 이스케이프 디코드를 구현하기로 결정했습니다. 더 느린 cp437 솔루션이어야하지만 모든 파이썬 버전에서 동일한 결과 가 산출되어야합니다.

# --- preparation

import codecs

def slashescape(err):
    """ codecs error handler. err is UnicodeDecode instance. return
    a tuple with a replacement for the unencodable part of the input
    and a position where encoding should continue"""
    #print err, dir(err), err.start, err.end, err.object[:err.start]
    thebyte = err.object[err.start:err.end]
    repl = u'\\x'+hex(ord(thebyte))[2:]
    return (repl, err.end)

codecs.register_error('slashescape', slashescape)

# --- processing

stream = [b'\x80abc']

lines = []
for line in stream:
    lines.append(line.decode('utf-8', 'slashescape'))



파이썬 3의 경우, 이것은 byte 에서 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')

산출:

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



Links