관리 메뉴

클라이언트/ 서버/ 엔지니어 " 게임 개발자"를 향한 매일의 공부일지

파이썬 날아오르기 1 - 파이썬과 유니코드 본문

프로그래밍 언어/파이썬

파이썬 날아오르기 1 - 파이썬과 유니코드

huenuri 2024. 10. 5. 06:21

간단한 프로그램이라면 파이썬 표준 라이브러리를 사용하겠지만, 그 가운데 몇 가지는 앞에서 배우지 않은 고급 개념을 미리 알아야만 이해할 수 있다. 이 내용은 조금 어렵지만 깊이 있는 파이썬 프로그램을 작성하고 싶고 싶다면 꼭 알아야 할 것 같다.


 

 

 

 

최초의 문자 셋, 아스키코드

최초의 컴퓨터가 발명되었을 때 문자를 처리하고자 컴퓨터마다 각각의 문자 셋을 정해놓고 문자를 처리하기 시작했다. 하지만 컴퓨터마다 각각의 문자 셋을 사용했더니 데이터 호환이 안 되는 문제가 발생했다. 이런 문제를 해결하고자 미국에서 최초로 문자 셋 표준인 아스키(ASKII)가 탄생하게 된다. 아스키라는 문자 셋 규칙을 정하고 이 규칙대로만 문자를 만들면 기종이 다른 컴퓨터 사이에도 문제없이 데이터를 주고받을 수 있었다.

하지만 아스키는 처리할 수 있는 문자 개수가 127개였는데, 영어권 국가에서 사용하는 영문자, 숫자 등을 처리하는 데는 부족함이 없었다.


 

 

 

유니코드의 등장

하지만 곧 비영어권 국가에서도 자신의 문자를 컴퓨터로 표현하고자 하는 요구가 생겼다. 아스키는 127개의 문자만을 다룰 수 있으므로 아스키를 사용할 수 없었다. 그래서 서유럽 문자셋인 ISO09950와 한국 문자 셋인 KSC5601 등이 등장하기 시작했다. 

이렇게 나라마다 문자 셋이 만들어지고 문자를 처리하는 방법이 점점 더 복잡해져 갔다. 가장 결정적인 문제는 하나의 문서에 여러 나라의 언어를 동시에 표현할 방법이 없다는 점이다.

 

이런 문제를 해결하고자 등장한 것이 유니코드이다. 유니코드는 모든 나라의 문자를 모두 포함하도록 넉넉하게 설계되었고 곧 세계 표준으로 자리 잡게 되었다.


 

 

 

유니코드로 문자열 다루기

이제 유니코드로 문자열을 다루는 방법을 알아보자. 파이썬에서 사용하는 문자열은 모두 유니코드 문자열이다.

 

인코딩하기

유니코드 문자열은 인코딩없이 그대로 파일에 적거나 다른 시스템으로 전송할 수 없다. 왜냐하면 유니코드 문자열은 단순히 문자 셋의 규칙이기 때문이다. 파일에 적거나 다른 시스템으로 전송하려면 바이트 문자열로 변환해야 한다. 이렇게 유니코드 문자열을 바이트 문자열로 바꾸는 것을 '인코딩'이라고 한다.

따라서 파일을 읽거나 네트워크를 통해 바이트 문자열을 수신할 때는 해당 바이트가 어떤 방식의 인코딩을 사용했는지 미리 알아야만 디코딩할 수 있다.

 

유니코드 문자열을 바이트 문자열로 바꾸는 방법은 다음과 같다.

 

 

유니코드 문자열을 바이트 문자열로 만들 때는 이처럼 utf-8과 같은 인코딩 방식을 인수로 넘겨주어야 한다. 인수를 생략하면 기본값인 utf-8로 동작한다. 출력해 보면 b 객체는 bytes 클래스의 객체라는 것을 알 수 있다.

 

 

여기서 한글이라는 유니코드 물자열을 아스키 방식으로 인코딩하려고 시도한다. 하지만 아스키 방식으로는 한글을 표현할 수 없으므로 오류가 발생한다.

"한글"이라는 유니코드 문자열을 바이트 문자열로 변경하는 인코딩 방식에는 여러 가지가 있다. 보통은 utf-8을 사용하지만, 다음과 같이 euc-kr로 인코딩할 수 있다.

 

 

utf-8로 인코딩했을 때와는 다른 바이트 문자열을 출력하는 것을 확인할 수 있다.


 

 

디코딩하기

이번에는 반대로 인코딩한 바이트 문자열을 유니코드 문자열로 변환하는 디코딩을 알아본다. euc-kr로 인코딩한 바이트 문자열은 euc-kr로만 디코딩해야 한다.

 

이와 달리 euc-kr로 인코딩한 바이트 문자열을 utf-8로 디코딩하려 한다면 어떻게 될까?

 

 

잘못된 인코딩 방식으로 디코딩하려고 하면 이처럼 오류가 발생한다.


 

 

 

입출력과 인코딩

인코딩과 관련해서 개발자가 가장 고생하는 부분은 바로 데이터 입출력 관련 작업이다. 문자열과 인코딩에 대한 개념만 확실히 이해하면 어렵지 않지만, 이를 이해하지 못하고 무작정 인코딩, 디코딩을 사용하면 다중 인코딩되거나 문자열이 꼬여 버리는 불상사가 발생하기도 한다.

파일을 읽거나 네트워크를 통해 데이터를 주고 받을 때 추천하는 방법은 다음과 같다.

  1. 입력으로 받은 바이트 문자열은 되도록 빨리 유니코드 문자열로 디코딩한다.
  2. 함수나 클래스 등에서는 유니코드 문자열만 사용한다.
  3. 입력에 대한 결과를 전송하는 마지막 부분에서만 유니코드 문자열을 바이트 문자열로 인코딩해서 반환한다.

 

이와 같은 규칙을 지킨다면 인코딩과관련해서 큰 어려움은 없을 것이다. 다음은 euc-kr 방식으로 작성한 파일을 읽고 변경하여 저장하는 예시이다.

 

 

파일을 읽는 open() 함수에는 encoding을 지정하여 파일을 읽는 기능이 있다.

 


 

 

 

학습을 마치고

인코딩 방식을 학습해보았다. 그래도 공부하길 정말 잘했다는 걸 느꼈다. 인코딩하는 방법도 알게 되었고 뿌듯한 시간이었다. 마지막에 소스 코드 인코딩 방식은 지금은 잘 사용하지 않는 방식이므로 생략했다.

다음 포스트에서는 클로저와 데코레이터에 대해서 학습해 볼 것이다.