파이썬 코딩을 더 깔끔하게! #3

Dunno·2021년 7월 3일
0

Better Way3. bytes와 str의 차이를 알아둬라.

Bytes와 str의 차이

Python3 에서는 bytes와 str 두 가지 타입으로 문자 시퀀스를 나타낸다.

Bytes 인스턴스

  • bytes 인스턴스는 부호가 없는 8바이트 데이터가 그대로 들어가며, 종종 아스키 인코딩을 사용해 내부 문자를 표시한다.
  • bytes 인스턴스에는 직접 대응하는 텍스트 인코딩이 없다.
  • 이진 데이터를 유니코드 데이터로 변환하기 위해서는 bytes의 decode메서드를 호출해야한다.
a = b'h\x65llo'
print(list(a))
print(a)

>>>
[104, 101, 108, 108, 111]
b'hello'

str 인스턴스

  • str 인스턴스는 사람이 사용하는 언어의 문자를 표현하는 유니코드 코드 포인트가 들어있다.
  • str인스턴스에는 직접 대응하는 이진 인코딩이 없다.
  • 유니코드 데이터를 이진 데이터로 변환하기 위해서는 str의 encode메서드를 호출해야 한다.
a = 'a\u0300 propos'
print(list(a))
print(a)

>>>
['a', '`', ' ', 'p', 'r', 'o', 'p', 'o', 's']
à propos

유니코드 샌드위치

파이썬 프로그램을 작성할 때 유니코드 데이터를 인코딩하거나 디코딩하는 부분을 인터페이스의 가장 먼 경계지점에 위치시키는 유니코드 샌드위치라는 방식을 사용하는 것이 좋다. 유니코드 샌드위치를 간략하게 설명하자면

  • 프로그램의 핵심 부분은 유니코드 데이터가 들어가 있는 str을 사용해야하고, 문자 인코딩에 대해 어떠한 가정도 하지 않는다.
  • 결론적으로 다양한 텍스트 인코딩으로 입력 데이터를 받아들이고, 출력 텍스트 인코딩은 한 가지로(UTF-8) 엄격히 제한한다.

문자를 표현하는 타입이 둘로 나뉘어 있기 때문에 파이썬 코드에서는 아래와 같은 두 가지 상황이 자주 발생한다.

  • UTF-8(또는 다른 인코딩 방식)로 인코딩된 8비트 시퀀스를 그대로 사용하고 싶다.
  • 특정 인코딩을 지정하지 않은 유니코드 문자열을 사용하긷도 한다.

이를 위해 두가지 도우미 함수를 사용하기도 한다.

  • bytes나 str 인스턴스를 받아서 항상 str인스턴스를 반환한다.
def to_str(bytes_or_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")))
print(repr(to_str("bar")))
print(repr(to_str(b"\xed\x95\x9c")))

>>>
"foo"
"bar"
"한"
  • bytes나 str 인스턴스를 받아서 항상 bytes를 반환한다.
def to_bytes(bytes_or_str):
	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")))
print(repr(to_bytes("bar")))
print(repr(to_bytes("한글")))

>>>
b'foo'
b'bar'
b'\xed\x95\x9c\xea\xb8\x80'

bytes와 str의 호환성

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

  1. bytes와 str이 똑같이 작동하는 것 처럼 보이지만 각각의 인스턴스는 서로 호환되지 않기 때문에 전달 중인 문자 시퀀스가 어떤 타입인지 항상 잘 알고 있어야 한다는 점이다.
  2. 내장함수인 open을 호출해 얻은 파일 핸들과 관련된 연산들이 디폴트로 유니코드 문자열을 요구하고 이진 바이트 문자열을 요구하지 않는다는 것이다.

기억해야 할 내용

  • bytes에는 8비트 값의 시퀀스가 들어 있고, str에는 유니코드 코드 포인트의 시퀀스가 들어있다.
  • 처리할 입력이 원하는 문자 시퀀스(8비트 값, UTF-8로 인코딩된 문자열, 유니코드 코드 포인트들)인지 확실히 하려면 도우미 함수를 사용하라.
  • bytes와 str 인스턴스를 (>, ==, +, % 와 같은) 연산자에 섞어서 사용할 수 없다.
  • 이진 데이터를 파일에서 읽거나 파일에 쓰고 싶으면 항상 이진 모드(rb 나 wb)로 파일을 열어라
  • 유니코드 데이터를 파일에서 읽거나 파일에 쓰고 싶을 때는 시스템 디폴트 인코딩에 주의하라. 인코딩 차이로 놀라고 싶지 않으면 open에 encoding 파라미터를 명시적으로 전달하라.

질문

repr() 함수란?

  • str() 함수는 사용자가 보기 쉬운 형태로 보여줄 때 사용되고, repr() 함수는 시스템이 해당 객체를 인식할 수 있는 공식적인 문자열로 나타내 줄 때 사용한다.
  • print함수가 무조건 str로 표현하기 때문에 repr함수를 입혀서 str이나 byte형태 있는 그대로 출력하게 해준다.
  • 디버깅 출력에도 종종 사용된다.

유니코드란?

  • 사람의 언어를 세계 공통으로 정리한 코드. 즉, 전 세계에서 일관되게 표현하고 다룰 수 있도록 설계된 산업 표준

0개의 댓글