Computer Engineering/Fluent Python 정리

Fluent Python Chapter 4. 텍스트와 바이트 (feat. 깨지지마라..)

jordan.bae 2022. 1. 9. 21:24

Chapter1의 Introduction 부분에서 이야기 한 것 처럼 지난 5년간 다양한 언어나 소프트웨어를 공부하고 이용하여 소프트웨어를 개발했는데 이것 저것 하다보니 자주 사용하는 언어임에도 불구하고 파이썬을 잘 활용하고 있느냐에 대한 답변을 자신있게 하기 어렵다고 느껴서 Fluent Python이라는 책을 공부하며 정리하고 있습니다. 올 해에는 새로운 기술들을 좋지만 기존에 활용하던 언어나 프레임워크 그리고 소프트웨어를 더 잘 사용할 수 있도록 깊게 공부할 수 있는 한해를 만들고 싶은 소망을 가지고 있습니다. 21장 까지 정리를 성공하고 맛있는걸 먹으면서 스스로 축하할 날이 어서 왔으면 좋겠네요!

 

지난 chapter 정리

Fluent Python Chapter 1. 파이썬 데이터 모델 (Feat. 일관성 있는 언어)

Fluent Python Chapter 2-1. Sequence (Sequence의 분류, listcomp, generator, tuple, slicing

Fluent Python Chapter 2-2. Sequence (bisect, deque, memoryview)

Fluent Python Chapter 3. Dictionary (feat. hashtable)

 

 

 

Chapter4는 텍스트와 비이트라는 주제였는데 생각보다 책이 잘 읽히지 않았습니다.

"그 이유가 무엇일까" 라고 생각해 봤는데 아래와 같은 이유인 것 같습니다.

- 다양한 국가의 언어나 다양한 특수 기호를 다룬 적이 아직 많지 않은 것 같습니다.

- 주로 회사에서는 모두 맥북을 사용하고, 최근에는 Container위에서 코드가 동작하니 system의 기본 인코딩/디코딩 방법이 달라서 생기는 문제를 겪지 않은 것 같습니다.

- 인코딩과 디코딩을 라이브러리단에서 많이 되어져있다보니 비즈니스 로직에서는 str(유니코드)를 다루게 되었던 것 같습니다. (Ex. Django에서 Request에 담긴 데이터들을 decoding해서 해주고 Response를 encoding해주는 역할은 Django 라이브러리에서 주로 하게 됩니다.)

 

 

그래도 책을 읽으면서 정리해보고 싶었던 내용을 모아서 정리해보겠습니다.

 

 

인코딩/디코딩과 관련된 Error

UnicodeEncodeError

-> str을 bytes로 변환할 때 변환 불가능한 문자가 나오면 발생한다.

+ errors인자를 통해 handling도 가능하다.

s = "chatper4 text and byes✌🏻"
s_cp949 = s.encode('cp949')
---------------------------------------------------------------------------
UnicodeEncodeError                        Traceback (most recent call last)
/var/folders/_k/w0m1fxfx2nngqbf5r4sp65lr0000gn/T/ipykernel_1387/2276848429.py in <module>
----> 1 s_cp949 = s.encode('cp949')

UnicodeEncodeError: 'cp949' codec can't encode character '\u270c' in position 22: illegal multibyte sequence


s_cp949
s_cp949 = s.encode('cp949', errors='ignore')
s_cp949
b'chatper4 text and byes'

UnicodeDecodeError

-> bytes를 str 변환할 때 변환 불가능한 byte가 나오면 발생한다.

+ errors인자를 통해 handling도 가능하다.

s = "chatper4 text and byes✌🏻"
s_utf8 = s.encode('utf-8')
s_utf8.decode('cp949')
---------------------------------------------------------------------------
UnicodeDecodeError                        Traceback (most recent call last)
/var/folders/_k/w0m1fxfx2nngqbf5r4sp65lr0000gn/T/ipykernel_1387/2927605434.py in <module>
----> 1 s_utf8.decode('cp949')

UnicodeDecodeError: 'cp949' codec can't decode byte 0xe2 in position 22: illegal multibyte sequence

 

 

SyntaxError

파이썬 3은 UTF-8을 소스 코드 기본 인코딩 방식으로 사용한다. 맨 위에 파일에 인코딩 선언 없이 UTF-8이 아닌 다른 방식으로 인코딩된 .py 모듈을 로딩하면 해당 에러가 발생한다.

 

 

 

바이트 시퀀스의 인코딩 방식을 알아내는 방법

정확하게 바이트 시퀀스의 인코딩 방식을 정확히 알아 내는 방법은 없다. 보통 통신 프로토콜에서는 Header에 인코딩 방법을 명시한다.

하지만 추정은 가능하다. bytes에 127이 넘는 값이 있따면 ASCII로 인코딩되어 있지 않음을 알 수 있다.

 

다양한 문자 인코등을 탐지하는 Charder 패키지는 이런 방법을 이용해서 30가지 인코딩 방식을 알아낸다. 

어떻게 추정하는지 궁금하신 분들은 공식문서의 how it works에 나와있다.

# 말 그대로 추정이다. 보편적인 문자들은 대부분의 인코딩 방식으로 모두 bytes로 가능하다..

import chardet

s = "chatper4 text and byes✌🏻"
s_utf8 = s.encode('utf-8')
chardet.detect(s_utf8)

{'encoding': 'Windows-1254',
 'confidence': 0.5496638462040557,
 'language': 'Turkish'}

 

 

유니코드 샌드위치

텍스트를 처리하는 최고의 방법은 '유니코드 샌드위치'다.

이 말은 가능하면 빠르게 bytes -> str으로 변환하고, 가능하면 가장 늦게 str -> bytes로 변환해야 한다는 것을 의미한다. 

 

bytes -> str

100% str (str로 변환 후에 프로그래밍(로직을 작성) 해라)

str -> bytes

 

 

이중 모드 str 및 bytes API

표준 라이브러중에 re, os 모듈은 str이나 bytes 인수를 모두 받으며, 인수의 자료형에 따라 다르게 작동하는 함수다.

정규표현식을 bytes를 다룰 때 사용해본 적은 없는데 다음에 bytes를 핸들링할 필요가 있다면 시도해봐야 겠다. 텍스트가 아닌 이미지나 영상같은 데이터를 처리할 때는 필요하지 않을까 싶지 않다.

 

이 외에도 책에서는 유니코드 정규화, 케이스 폴딩, 유니코드 텍스트 정렬하기 등을 다루고 있다.

 

반응형