이 코드를 사용하여 외부 프로그램에서 표준 출력을 얻습니다.
>>> from subprocess import *
>>> command_stdout = Popen(['ls', '-l'], stdout=PIPE).communicate()[0]
communi () 메소드는 바이트 배열을 리턴합니다.
>>> 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'
그러나 출력을 일반 Python 문자열로 사용하고 싶습니다. 다음과 같이 인쇄 할 수 있습니다.
>>> 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에서도 괜찮기를 바랍니다.
답변
문자열을 생성하려면 bytes 객체를 디코딩해야합니다.
>>> 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'
답변
바이트 문자열을 디코딩하여 문자 (유니 코드) 문자열로 바꿔야합니다.
파이썬 2에서
encoding = 'utf-8'
'hello'.decode(encoding)
또는
unicode('hello', encoding)
파이썬 3에서
encoding = 'utf-8'
b'hello'.decode(encoding)
또는
str(b'hello', encoding)
답변
나는이 방법이 쉽다고 생각한다.
>>> bytes_data = [112, 52, 52]
>>> "".join(map(chr, bytes_data))
'p44'
답변
인코딩을 모르는 경우 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
latin-1
파이썬 2에서 널리 사용되는 (기본값?) 코드 에도 동일하게 적용됩니다 . 코드 페이지 레이아웃 에서 누락 된 부분을보십시오 ordinal not in range
. 파이썬이 악명 높게 질식하는 곳 입니다.
UPDATE 20150604 : Python 3에는 surrogateescape
데이터 손실 및 충돌없이 바이너리 데이터로 물건을 인코딩 하는 데 오류 전략 이 있다는 소문이 있지만 [binary] -> [str] -> [binary]
성능과 안정성을 모두 검증 하려면 변환 테스트가 필요합니다 .
UPDATE 20170116 : Nearoo의 의견 덕분에 backslashreplace
오류 처리기로 알 수없는 모든 바이트를 이스케이프 처리 할 수 있습니다. 그것은 Python 3에서만 작동 하므로이 해결 방법으로도 다른 Python 버전에서 일관성없는 출력을 얻을 수 있습니다.
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'))
자세한 내용은 Python의 유니 코드 지원 을 참조하십시오.
업데이트 20170119 : Python 2와 Python 3 모두에서 작동하는 슬래시 이스케이프 디코딩을 구현하기로 결정했습니다. cp437
솔루션 보다 느려 야하지만 모든 Python 버전에서 동일한 결과 를 생성해야합니다 .
# --- 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'))
답변
Python 3 에서 기본 인코딩은입니다 "utf-8"
. 직접 사용할 수 있습니다.
b'hello'.decode()
어느 것이
b'hello'.decode(encoding="utf-8")
반면 에 Python 2 에서는 인코딩이 기본 문자열 인코딩으로 기본 설정됩니다. 따라서 다음을 사용해야합니다.
b'hello'.decode(encoding)
encoding
원하는 인코딩은 어디에 있습니까?
참고 : 키워드 인수에 대한 지원은 Python 2.7에서 추가되었습니다.
답변
나는 당신이 실제로 이것을 원한다고 생각합니다 :
>>> from subprocess import *
>>> command_stdout = Popen(['ls', '-l'], stdout=PIPE).communicate()[0]
>>> command_text = command_stdout.decode(encoding='windows-1252')
아론의 대답은 당신 이 사용 인코딩. 그리고 Windows는 ‘windows-1252’를 사용한다고 생각합니다. 콘텐츠에 비정상적인 (ASCII 이외의) 문자가있는 경우에만 문제가되지만 차이가 있습니다.
그런데,이 사실 않습니다 문제는 이유는 파이썬 바이너리와 텍스트 데이터에 대한 서로 다른 두 가지 유형을 사용하여 이동한다는 것입니다 : 당신이 그것을 말하지 않는 한 인코딩을 모르고 있기 때문에, 그들 사이에 마술 변환 할 수 없습니다! 아는 유일한 방법은 Windows 설명서를 읽거나 여기를 읽는 것입니다.
답변
universal_newlines를 True로 설정하십시오.
command_stdout = Popen(['ls', '-l'], stdout=PIPE, universal_newlines=True).communicate()[0]