파이썬 3에서 문자열을 바이트로 변환하는 가장 좋은 방법은 무엇입니까?


858

TypeError 에 대한 답변에서 볼 수 있듯이 문자열을 바이트로 변환하는 두 가지 방법이 있습니다 . 'str'은 버퍼 인터페이스를 지원하지 않습니다.

이 중 어떤 것이 더 나은 파이썬적인 방법입니까? 아니면 개인적인 취향의 문제일까요?

b = bytes(mystring, 'utf-8')

b = mystring.encode('utf-8')

42
인코딩 / 디코딩을 사용하는 것이 더 일반적이며 더 명확합니다.
Lennart Regebro

11
@LennartRegebro 나는 닫습니다. 더 일반적인 경우에도 "bytes ()"를 읽으면 어떻게하는지 알고 있지만, encode ()는 바이트로 인코딩한다고 생각하지 않습니다.
m3nda

2
@이 때까지 사용하는 것이 이유입니다 erm3nda 않습니다 , 당신은 그 느낌은 한 걸음 더 가까이 유니 코드 선에.
Lennart Regebro

3
@LennartRegebro bytes(item, "utf8")명시 적이 암시 적보다 낫기 때문에 사용하기에 충분하다고 생각합니다 . str.encode( )기본적으로 바이트로 자동 설정되어 더 많은 유니 코드 zen이지만 덜 명시 적 젠을 만듭니다. 또한 "공통"은 내가 좋아하는 용어가 아닙니다. 또한, 및 표기법 과 bytes(item, "utf8")더 비슷합니다 . 내가 당신의 이유를 이해하기 위해 너무 멍청한 경우 내 사과드립니다. 감사합니다. str()b"string"
m3nda

4
@ erm3nda 당신이 수락 된 답변을 읽으면 encode()전화하지 않는 것을 볼 수 있습니다 bytes(). 물론 그것이 바로 질문이 아닌 이유입니다.
Mark Ransom

답변:


570

에 대한 문서를 보면 다음을 bytes가리 킵니다 bytearray.

바이트 어레이 ([source [, encoding [, errors]]])

새로운 바이트 배열을 돌려줍니다. 바이트 배열 유형은 0 <= x <256 범위의 가변 정수 시퀀스입니다. 가변 시퀀스 유형에 설명 된 대부분의 일반적인 가변 시퀀스 방법과 바이트 유형에있는 대부분의 메서드가 있습니다 (바이트 및 바이트 참조). 바이트 배열 방법.

선택적 source 매개 변수를 사용하여 몇 가지 다른 방식으로 배열을 초기화 할 수 있습니다.

문자열 인 경우 인코딩 (및 선택적으로 오류) 매개 변수도 제공해야합니다. 그런 다음 bytearray ()는 str.encode ()를 사용하여 문자열을 바이트로 변환합니다.

정수이면 배열의 크기가 설정되며 null 바이트로 초기화됩니다.

버퍼 인터페이스를 준수하는 객체 인 경우 객체의 읽기 전용 버퍼를 사용하여 바이트 배열을 초기화합니다.

iterable 인 경우 배열의 초기 내용으로 사용되는 0 <= x <256 범위의 정수 iterable이어야합니다.

인수가 없으면 크기가 0 인 배열이 작성됩니다.

따라서 bytes문자열을 인코딩하는 것 이상을 할 수 있습니다. Pythonic은 모든 유형의 소스 매개 변수로 생성자를 호출 할 수있게합니다.

문자열을 인코딩 할 some_string.encode(encoding)때는 생성자를 사용하는 것보다 더 파이썬 적이라고 생각합니다 . 생성자가 가장 많이 문서화되어 있기 때문입니다. "이 문자열을 사용하여이 인코딩으로 인코딩합니다"가 더 명확 bytes(some_string, encoding)합니다. 건설자.

편집 : 나는 파이썬 소스를 확인했다. 당신이 유니 코드 문자열을 전달하는 경우 bytes의 CPython을 사용하여, 그것은 호출 PyUnicode_AsEncodedString 의 구현이다 encode; encode직접 전화하면 간접적 인 수준을 건너 뜁니다 .

또한 Serdalis의 의견을 참조하십시오. 역률이 높고 대칭이 unicode_string.encode(encoding)좋기 때문에 더 Pythonic byte_string.decode(encoding)입니다.


73
파이썬 문서에서 좋은 주장과 인용문을 가지고 +1. 또한 unicode_string.encode(encoding)멋지게 일치 bytearray.decode(encoding)당신이 당신의 문자열 등을 할 때.
Serdalis

6
bytearray가변 객체가 필요할 때 사용됩니다. 간단한 strbytes변환 에는 필요하지 않습니다 .
hamstergene

8
@ EugeneHomyakov 이것은 bytearray문서가 bytes세부 사항을 제공하지 않는다는 것을 제외하고 는 아무런 관련이 없습니다 bytearray.
agf

1
간단히 말해서 파이썬에서 주의 할 점 은 bytes다음과 같습니다. bytes 인수를 정수 인수를 가진 함수로 사용하지 마십시오. v2에서는 바이트가 str의 별명이므로 바이트 (바이트)로 변환 된 정수를 리턴하고 v3에서는 제공된 널 문자 수를 포함하는 바이트 스트링을 리턴합니다. 예를 들어, v3 표현식 bytes (6) 대신 동등한 b '\ x00'* 6을 사용하십시오. 이는 각 버전에서 동일하게 작동합니다.
holdenweb

2
이진 데이터를 문자열로 변환하려는 경우 0x00에서 0xFF (0-255)의 전체 범위 byte_string.decode('latin-1')utf-8다루지 않는 것과 같은 것을 사용해야 할 것입니다 . 파이썬 문서 를 확인하십시오. 더 많은 정보.
iggy12345

346

생각보다 쉽습니다.

my_str = "hello world"
my_str_as_bytes = str.encode(my_str)
type(my_str_as_bytes) # ensure it is byte representation
my_decoded_str = my_str_as_bytes.decode()
type(my_decoded_str) # ensure it is string representation

37
그는 그것을하는 방법을 알고 있으며, 어떤 방법이 더 좋은지 묻고 있습니다. 질문을 다시 읽으십시오.
agf

30
참고 : str.decode (bytes)가 나를 위해 작동하지 않았습니다 (Python 3.3.3은 "type object 'str'에는 'decode'속성이 없습니다"). 대신 bytes.decode ()를 사용했습니다.
Mike

6
@Mike : obj.method()구문 대신 cls.method(obj)구문을 사용하십시오 (예 : bytestring = unicode_text.encode(encoding)및) unicode_text = bytestring.decode(encoding).
jfs

2
... 불필요하게 언 바운드 메소드를 만든 다음 self이를 첫 번째 인수로 전달합니다.
Antti Haapala

2
@KolobCanyon이 질문은 이미 올바른 방법을 보여줍니다 encode. 문자열에서 바인딩 된 메서드 로 호출 합니다. 이 대답은 대신 바인딩되지 않은 메소드를 호출하고 문자열을 전달해야 함을 제안합니다. 그것은 답변에서 유일한 새로운 정보이며, 틀 렸습니다.
abarnert

144

절대적으로 가장 좋은 방법은 어느 쪽도 2의 없지만, 3. 첫 번째 매개 변수는 Python 3.0부터 기본값 입니다. 따라서 가장 좋은 방법은encode 'utf-8'

b = mystring.encode()

기본 인수가 문자열에없는 결과 때문에도 빨라집니다 "utf-8"C 코드에 있지만 NULL, 이는 훨씬 더 빨리 확인하세요!

다음은 몇 가지 타이밍입니다.

In [1]: %timeit -r 10 'abc'.encode('utf-8')
The slowest run took 38.07 times longer than the fastest. 
This could mean that an intermediate result is being cached.
10000000 loops, best of 10: 183 ns per loop

In [2]: %timeit -r 10 'abc'.encode()
The slowest run took 27.34 times longer than the fastest. 
This could mean that an intermediate result is being cached.
10000000 loops, best of 10: 137 ns per loop

경고에도 불구하고 반복 실행 후 시간은 매우 안정적이었습니다. 편차는 ~ 2 %에 불과했습니다.


encode()Python 2에서 기본 문자 인코딩은 ASCII 이므로 인수없이 사용 하는 것은 Python 2와 호환되지 않습니다 .

>>> 'äöä'.encode()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)

2
여기에는 (a) 문자열이 순수한 ASCII이므로 내부 저장소가 이미 UTF-8 버전이므로 코덱을 찾는 것이 거의 유일한 비용이며 (b) 문자열이 작기 때문에 상당한 차이가 있습니다. 따라서 인코딩해야하더라도 큰 차이는 없습니다. 라고 사용해보십시오 '\u00012345'*10000. 둘 다 내 노트북에서 28.8us를 사용합니다. 반올림 오류에서 50ns가 추가로 손실 될 수 있습니다. 물론 이것은 매우 극단적 인 예입니다. 그러나 'abc'반대 방향에서도 마찬가지입니다.
abarnert

@abarnert true이지만, 그럼에도 불구하고 인수를 문자열로 전달할 이유가 없습니다.
Antti Haapala

이것에 따르면, 기본 논증은 항상 "절대적으로 최선의 방법"입니다. 이런 종류의 속도 분석은 C 코드를 논의하는 데있어 과장된 것 같습니다. 통역 된 언어로는 말이 없습니다.
hmijail, 사임 자
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.