3. bytes와 str의 차이를 알아두라

hyuckhoon.ko·약 13시간 전
0

Python

목록 보기
3/3
post-thumbnail

1. bytes

>>> a = b'h\x65llo'
>>> a
b'hello'
>>> print(list(a))
[104, 101, 108, 108, 111]
>>> print(a)
b'hello'

2. 코드 포인트

사람이 사용하는 언어의 문자를 표현하는 유니코드 코드 포인트(code point)

>>> a = 'a\u0300 propos'
>>> a
'à propos'
>>> a
'à propos'
>>> print(list(a))
['a', '̀', ' ', 'p', 'r', 'o', 'p', 'o', 's']
>>> print(a)
à propos

3. 유니코드 샌드위치

유니코드 샌드위치 (Unicode Sandwich)"는 Python 3를 비롯한 여러 언어/환경에서 문자열 처리의 일관성을 유지하기 위한 전략이다. 텍스트 인코딩 문제를 피하기 위한 좋은 컨벤션이다.

입력 (bytes) ──[디코딩]──▶ 내부 처리 (Unicode) ──[인코딩]──▶ 출력 (bytes)
  • 파이썬 프로그래밍을 작성할 때 유니코드 데이터를 인코딩하거나 디코딩하는 부분을 인터페이스의 가장 먼 경계 지점에 위치시키는 것

    • 프로그램의 핵심 부분은 유니코드 데이터가 들어 있는 str을 사용해야 하고, 문자 인코딩에 대해 어떠한 가정도 해서는 안 된다.
    • 이렇게 하면 프로그램은 다양한 텍스트 인코딩(Latin-1, Shift, JIS, euc-kr, cp949, Big5 등)으로 입력 데이터를 받아들일 수 있다.
    • 출력 인코딩은 한 가지(UTF-8이 이상적)로 엄격히 제한할 수 있다.

4. 헬퍼 함수 예시

1. bytes나 str 인스턴스를 받고 항상 str 인스턴스를 리턴

def to_str(bytes_or_str) -> str:
    if isinstance(bytes_or_str, bytes):
        value = bytes_or_str.decode('utf-8')
    else:
        value = bytes_or_str
    return value


print(repr(to_str(b'foo')))  # 'foo'
print(repr(to_str('bar')))  # 'bar'
print(repr(to_str(b'\xed\x95\x9c')))  # '한'

2. bytes나 str 인스턴스를 받아서 항상 bytes 인스턴스를 리턴

def to_bytes(bytes_or_str) -> bytes:
    if isinstance(bytes_or_str, str):
        value = bytes_or_str.encode('utf-8')
    else:
        value = bytes_or_str
    return value


print(repr(to_bytes(b'foo')))  # b'foo'
print(repr(to_bytes('bar')))  # b'bar'
print(repr(to_bytes('한글')))  # b'\xed\x95\x9c\xea\xb8\x80'

이진 8비트 값과 유니코드 문자열을 파이썬에서 다룰 때 꼭 기억해야 할 두가지가 있다.

1. bytes와 str은 똑같이 작동하는 것처럼 보이지만, 각각의 인스턴스는 서로 호환되지 않는다.

print(b'foo' + b'bar')  # b'foobar'
print('boo' + 'bar')  # foobar

그러나

print('foo' + b'bar')
print('foo' + b'bar')
      ~~~~~~^~~~~~~~

TypeError: can only concatenate str (not "bytes") to str

마찬가지로,

print(b'foo' + 'bar')
print(b'foo' + 'bar')
      ~~~~~~~^~~~~~~

TypeError: can't concat str to bytes

0개의 댓글