EXCELSIOR

BETTER WAY 03 - bytes, str, unicode의 차이점을 알자 본문

Python/Effective Python

BETTER WAY 03 - bytes, str, unicode의 차이점을 알자

Excelsior-JH 2018. 1. 22. 16:17

BETTER WAY 03 - bytes, str, unicode의 차이점을 알자

Item03 - Know the Differences Between bytes, str, and unicode



  • Python3 에서는 bytes와 str 두 가지 타입으로 문자 시퀀스를 나타냄
  • bytes 인스턴스는 로(raw) 8비트 값을 저장함
  • str 인스턴스는 Unicode(유니코드, 세계의 모든 문자를 컴퓨터에서 일관되게 표현하고 다룰 수 있도록 설계된 산업 표준) 문자를 저장함
  • Unicode 문자를 Binary data(8-bit)로 표현하는 방법 중 가장 대표적인 인코딩은 UTF-8이 있음
    • UTF-8: 유니코드를 위한 가변 길이 문자 인코딩 방식 중 하나이며, Universal Coded Character Set Transformation Format - 8-bit의 약어
    • UTF-8 인코딩은 유니코드 한 문자를 나타내기 위해 1 ~ 4바이트까지 사용함
  • 문자 타입이 분리되어 있는 Python에서는 다음 두가지 상황이 생길 수 있음
    • UTF-8(또는 다른 인코딩)으로 인코딩된 문자인 Raw 8 bit 값을 처리하려는 상황
    • 인코딩이 없는 유니코드 문자를 처리하려는 상황

Python3 에서는 먼저 str이나 bytes를 입력으로 받고 str을 반환하는 메소드가 필요하다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import os
 
 
 
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 # str 인스턴스
 
 
repr(to_str(b'foo'))
## 출력
# >>> "'foo'"
 
repr(to_str('foo'))
## 출력
# >>> "'foo'"
cs


str이나 bytes를 받고 bytes를 반환하는 메소드도 필요하다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
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 # bytes 인스턴스
 
repr(to_bytes(b'foo'))
## 출력
# >>> "b'foo'"
 
repr(to_bytes('foo'))
## 출력
# >>> "b'foo'"
cs



Python3는 내장 함수 Open의 파일 핸들의 연산은 기본으로 UTF-8 인코딩을 사용한다. (Python2.x 에서는 바이너리 인코딩을 사용) 따라서, 아래의 소스코드 처럼 문자 쓰기 모드(w)를 사용하면 에러가 난다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
with open('./tmp/random.txt''w') as f:
    f.write(os.urandom(10))
 
 
''' 아래와 같은 에러가 발생함
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-14-9778ddf3f194> in <module>()
      1 with open('./tmp/random.txt', 'w') as f:
----> 2     f.write(os.urandom(10))
TypeError: write() argument must be str, not bytes
Python3에서 이러한 문제를 해결하려면 문자 쓰기 모드(wb)를 사용해야한다.
'''
cs



Python3에서 이러한 문제를 해결하려면 문자 쓰기 모드(wb)를 사용해야한다.


1
2
with open('./tmp/random2.txt''wb') as f:
    f.write(os.urandom(10))
cs


정리

  • Python3에서 bytes는 8비트 값을 저장하고, str은 유니코드 문자를 저장한다.
  • 위의 변환함수(교재에서는 헬퍼함수)를 이용해서 처리할 입력값이 원하는 문자 시퀀스 타입(8비트, UTF-8, Unicode 등)으로 처리해준다.
  • 바이너리 데이터를 파일에서 읽거나 쓸 때는 파일을 바이너리 모드(rb 또는 wb)로 open한다.


Comments