[python] python3 힘들게 배우기 #7
ex22. 복습
간단한 복습에 대한 내용이다. ex1~ex21까지의 내용을 복습해 보자.
ex23. String, Bytes, Character Encodings
상당히 어려운 수준의 예제가 처음으로 등장한다. 이번 예제는 반드시 전부 이해하고 갈 필요 없을 정도로 어렵다. 이번 예제에서는 다음과 같은 개념에 대해 배우는데..
- 현대 컴퓨터들이 사람의 언어를 어떻게 display하고 처리하는지와 python3이 어떻게
string
을 부르는지? - 어떻게 Python의 string을
bytes
를 이용하여 “encode” 및 “decode”하는지? - 어떻게 byte handling 의 에러를 처리하는지?
- 어떻게 코드를 읽고 지금까지 보지 못했던 것을 찾는지?
이번에는 함수들을 먼저 짚고 넘어가도록 하자.
str.strip([chars])
여기의 내용을 참고했다. (왠만한 기본적인 것은 공식 사이트를 이용하는것이 설명이 훨씬 좋더라..specific한 질문은 stackoverflow가 좋지만)strip에서 알 수 있듯이, 문자의 앞 뒤를 잘러버린다. [chars]로 이루어진 모든 조합 에 대해서 생략을 해준다. [chars]가 omit될 경우 공백을 없애준다. 아래 예시를 살펴보자.
' I AM A BOY '.strip() # >>> 'I AM A BOY'
'@$ I AM A BOY@$ $'.strip('@$ ') # >>> 'I AM A BOY'
str.encode(encoding="utf-8", errors="strict")
여기를 참고했다. str
을 원하는 형식으로 인코딩 해주는 것.
bytes.decode(encoding="utf-8", errors="strict")
여기의 내용을 참고하도록 하자. byte로 되어있는 것을 디코딩하여 인간의 언어로 번역해 준다.
그럼 인코딩과 디코딩이란 무엇일까? 컴퓨터의 문자들이 나타내어지는 원리는 아주 간단하다고 볼 수 있다. 0과 1의 조합을 각각의 언어에 1:1 매칭시켜서 나타내어준것에 불과하다. 그리고 이런 0과 1들은 ‘bit’라고 불리운다. 예를 들면 8자리 2진법숫자를 이용한다고 가정했을 때 우리는 2의 8승인 256개의 경우의 수를 가질 수 있다. (00000000 ~ 11111111, 십진수로 하면 0 ~ 255) 결국 “encode”가 의미하는 바는 무엇인가? 어떤 숫자가 어떤 인간의 언어를 나타내는지 약속한 것에 불과한 것이다.
오늘날에는 우리는 8bit(8자리 2진수)를 1byte라고 부르고 있다. 아무튼, 컴퓨터 발전사 초기에는 이 약속에도 굉장히 여러 가지 버전이 있었고 사람들이 각자 쓰는 방식이 달랐지만 결국에는 우리가 흔히 ASCII라고 부르는 숫자-알파벳 매칭 방식(American Standard Code for Information Interchange)이 남게 된다. 예시를 같이 보도록 하자. 숫자 90은 알파벳 Z에 해당하고 bit에 해당하는 것은 1011010 이다. 즉 모든 알파벳은 0~256개의 차고 넘치는 숫자들에 1:1로 대응시킬 수 있게 되는데, 이 말은 어떤 알파벳(+@)을 쓰는 데 컴퓨터가 먹는 용량은 8bit(1byte)면 충분하다는 것이다. KIM이라는 단어를 표현하는데는? 3byte면 충분하다.
문제는 ASCII는 단순히 영어와 그 비슷한 알파벳을 가진 언어에만 국한되어 사용될 수 있는 방식이고, 0~255 즉 256개의 조합을 이용해서는 충분하겠지만 전 세계의 다양한 언어방식을 사용하는데는 충분치 않다는 점이다.
이 문제를 해결하기 위해서 만들어진 것이 바로 유니코드(Unicode)다. universal encoding이라는 뜻으로서 모든 인간 언어를 이용하기 위해 만들어졌다. 32bit의 큰 용량으로서 이것만 있으면 2^32승의 어마무시한 문자를 표현할 수 있는 가짓수를 가지게 된다.
하지만 이는 또 굉장한 용량 낭비를 초래할 수 있기 떄문에, 한 걸음 더 나아간 것이 바로 utf-8 방식이며 이는 Unicode Transformation Format for 8 bit의 약자이다. 의미는 8bit의 인코딩 체계를 이용하되 필요한 경우에만 unicode를 이용하는 방법을 사용함으로서 낭비되는 용량을 줄이는 방법이다. 이것이 Python에서 이용하는 인코딩 방식이다.
자.. 그렇다면 한번 코딩으로 들어가 보자. 먼저 여기 서 세계 각국의 언어가 ‘utf-8’을 이용하여(인코딩방식) 작성되어 있는 파일을 하나 다운받자.
아래와 같은 코드를 작성하자.
# import argv from sys와 동일한 과정
import sys
script, encoding_type, error_type = sys.argv
# line 변수에 언어를 하나씩 넣어줌. 재귀함수임에 주목
def main(file, encoding_type, error_type):
line = file.readline()
if line:
print_line(line, encoding_type, error_type)
main(file, encoding_type, error_type)
#각 언어를 한번은 인코딩 하고 다시 그것을 디코딩하여 각각 프린트한다.
def print_line(text_line, encoding, error_type):
next_lang = text_line.strip()
raw_bytes = next_lang.encode(encoding, errors = error_type)
cooked_string = raw_bytes.decode(encoding, errors = error_type)
print(raw_bytes, " <====> ", cooked_string)
#파일 open
language = open("language.txt", encoding = "utf-8")
#메인함수 시작
main(language, encoding_type, error_type)
지금까지 수행했던 것에 비하면 상당히 복잡한 코드이다. 파워셀을 키고 python ex23.py utf-8 strict
로 실행해보자. 물론 languages.txt파일은 ex23.py와 같은 폴더에 있어야겠죠?
먼저 main함수를 통해 각 언어를 하나씩 line변수에 집어넣는 일을 하고, line에 값이 있을 경우(즉 true일 경우) if 문 이하를 실행하도록 만들어 놨다. if문에는 print_line함수와 함께 다시 main함수를 넣어놨는데.. 재귀함수의 개념을 이렇게 바로 넣다니!
하여튼, print_line함수는 다른게 아니고 그냥 인코딩과 디코딩 한 것을 한번씩 보여주는 함수이다. 즉 string은 인코딩하면 raw bytes형태가 되는 거고, raw bytes 는 디코딩하면 string이 되는 것 이다.
raw bytes의 형태라는 것을 알 수 있는 것이 바로 b' '
이며 파이썬으로 하여금 b
안에 있는 것이 raw byte라는 것이라고 말해주는 것과 같다.
위 사항을 수행하면
b'Afrikaans' <====> Afrikaans
b'\xe1\x8a\xa0\xe1\x88\x9b\xe1\x88\xad\xe1\x8a\x9b' <====> አማርኛ
b'\xd0\x90\xd2\xa7\xd1\x81\xd1\x88\xd3\x99\xd0\xb0' <====> Аҧсшәа
b'\xd8\xa7\xd9\x84\xd8\xb9\xd8\xb1\xd8\xa8\xd9\x8a\xd8\xa9' <====> العربية
b'Aragon\xc3\xa9s' <====> Aragonés
b'Arpetan' <====> Arpetan
b'Az\xc9\x99rbaycanca' <====> Azərbaycanca
b'Bamanankan' <====> Bamanankan
b'\xe0\xa6\xac\xe0\xa6\xbe\xe0\xa6\x82\xe0\xa6\xb2\xe0\xa6\xbe' <====> বাংলা
b'B\xc3\xa2n-l\xc3\xa2m-g\xc3\xba' <====> Bân-lâm-gú
b'\xd0\x91\xd0\xb5\xd0\xbb\xd0\xb0\xd1\x80\xd1\x83\xd1\x81\xd0\xba\xd0\xb0\xd1\x8f' <====> Беларуская
b'\xd0\x91\xd1\x8a\xd0\xbb\xd0\xb3\xd0\xb0\xd1\x80\xd1\x81\xd0\xba\xd0\xb8' <====> Български
b'Boarisch' <====> Boarisch
b'Bosanski' <====> Bosanski
b'\xd0\x91\xd1\x83\xd1\x80\xd1\x8f\xd0\xb0\xd0\xb4' <====> Буряад
b'Catal\xc3\xa0' <====> Català
b'\xd0\xa7\xd3\x91\xd0\xb2\xd0\xb0\xd1\x88\xd0\xbb\xd0\xb0' <====> Чӑвашла
b'\xc4\x8ce\xc5\xa1tina' <====> Čeština
b'Cymraeg' <====> Cymraeg
b'Dansk' <====> Dansk
b'Deutsch' <====> Deutsch
b'Eesti' <====> Eesti
b'\xce\x95\xce\xbb\xce\xbb\xce\xb7\xce\xbd\xce\xb9\xce\xba\xce\xac' <====> Ελληνικά
b'Espa\xc3\xb1ol' <====> Español
b'Esperanto' <====> Esperanto
b'\xd9\x81\xd8\xa7\xd8\xb1\xd8\xb3\xdb\x8c' <====> فارسی
b'Fran\xc3\xa7ais' <====> Français
b'Frysk' <====> Frysk
b'Gaelg' <====> Gaelg
b'G\xc3\xa0idhlig' <====> Gàidhlig
b'Galego' <====> Galego
b'\xed\x95\x9c\xea\xb5\xad\xec\x96\xb4' <====> 한국어
b'\xd5\x80\xd5\xa1\xd5\xb5\xd5\xa5\xd6\x80\xd5\xa5\xd5\xb6' <====> Հայերեն
b'\xe0\xa4\xb9\xe0\xa4\xbf\xe0\xa4\xa8\xe0\xa5\x8d\xe0\xa4\xa6\xe0\xa5\x80' <====> हिन्दी
b'Hrvatski' <====> Hrvatski
b'Ido' <====> Ido
b'Interlingua' <====> Interlingua
b'Italiano' <====> Italiano
b'\xd7\xa2\xd7\x91\xd7\xa8\xd7\x99\xd7\xaa' <====> עברית
b'\xe0\xb2\x95\xe0\xb2\xa8\xe0\xb3\x8d\xe0\xb2\xa8\xe0\xb2\xa1' <====> ಕನ್ನಡ
b'Kapampangan' <====> Kapampangan
b'\xe1\x83\xa5\xe1\x83\x90\xe1\x83\xa0\xe1\x83\x97\xe1\x83\xa3\xe1\x83\x9a\xe1\x83\x98' <====> ქართული
b'\xd2\x9a\xd0\xb0\xd0\xb7\xd0\xb0\xd2\x9b\xd1\x88\xd0\xb0' <====> Қазақша
b'Krey\xc3\xb2l ayisyen' <====> Kreyòl ayisyen
b'Latga\xc4\xbcu' <====> Latgaļu
b'Latina' <====> Latina
b'Latvie\xc5\xa1u' <====> Latviešu
b'L\xc3\xabtzebuergesch' <====> Lëtzebuergesch
b'Lietuvi\xc5\xb3' <====> Lietuvių
b'Magyar' <====> Magyar
b'\xd0\x9c\xd0\xb0\xd0\xba\xd0\xb5\xd0\xb4\xd0\xbe\xd0\xbd\xd1\x81\xd0\xba\xd0\xb8' <====> Македонски
b'Malti' <====> Malti
b'\xe0\xa4\xae\xe0\xa4\xb0\xe0\xa4\xbe\xe0\xa4\xa0\xe0\xa5\x80' <====> मराठी
b'\xe1\x83\x9b\xe1\x83\x90\xe1\x83\xa0\xe1\x83\x92\xe1\x83\x90\xe1\x83\x9a\xe1\x83\xa3\xe1\x83\xa0\xe1\x83\x98' <====> მარგალური
b'\xd9\x85\xd8\xa7\xd8\xb2\xd9\x90\xd8\xb1\xd9\x88\xd9\x86\xdb\x8c' <====> مازِرونی
b'Bahasa Melayu' <====> Bahasa Melayu
b'\xd0\x9c\xd0\xbe\xd0\xbd\xd0\xb3\xd0\xbe\xd0\xbb' <====> Монгол
b'Nederlands' <====> Nederlands
b'\xe0\xa4\xa8\xe0\xa5\x87\xe0\xa4\xaa\xe0\xa4\xbe\xe0\xa4\xb2 \xe0\xa4\xad\xe0\xa4\xbe\xe0\xa4\xb7\xe0\xa4\xbe' <====> नेपाल भाषा
b'\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e' <====> 日本語
b'Norsk bokm\xc3\xa5l' <====> Norsk bokmål
b'Nouormand' <====> Nouormand
b'Occitan' <====> Occitan
b'O\xca\xbbzbekcha/\xd1\x9e\xd0\xb7\xd0\xb1\xd0\xb5\xd0\xba\xd1\x87\xd0\xb0' <====> Oʻzbekcha/ўзбекча
b'\xe0\xa8\xaa\xe0\xa9\xb0\xe0\xa8\x9c\xe0\xa8\xbe\xe0\xa8\xac\xe0\xa9\x80' <====> ਪੰਜਾਬੀ
b'\xd9\xbe\xd9\x86\xd8\xac\xd8\xa7\xd8\xa8\xdb\x8c' <====> پنجابی
b'\xd9\xbe\xda\x9a\xd8\xaa\xd9\x88' <====> پښتو
b'Plattd\xc3\xbc\xc3\xbctsch' <====> Plattdüütsch
b'Polski' <====> Polski
b'Portugu\xc3\xaas' <====> Português
b'Rom\xc3\xa2n\xc4\x83' <====> Română
b'Romani' <====> Romani
b'\xd0\xa0\xd1\x83\xd1\x81\xd1\x81\xd0\xba\xd0\xb8\xd0\xb9' <====> Русский
b'Seeltersk' <====> Seeltersk
b'Shqip' <====> Shqip
b'Simple English' <====> Simple English
b'Sloven\xc4\x8dina' <====> Slovenčina
b'\xda\xa9\xd9\x88\xd8\xb1\xd8\xaf\xdb\x8c\xdb\x8c \xd9\x86\xd8\xa7\xd9\x88\xdb\x95\xd9\x86\xd8\xaf\xdb\x8c' <====> کوردیی ناوەندی
b'\xd0\xa1\xd1\x80\xd0\xbf\xd1\x81\xd0\xba\xd0\xb8 / srpski' <====> Српски / srpski
b'Suomi' <====> Suomi
b'Svenska' <====> Svenska
b'Tagalog' <====> Tagalog
b'\xe0\xae\xa4\xe0\xae\xae\xe0\xae\xbf\xe0\xae\xb4\xe0\xaf\x8d' <====> தமிழ்
b'\xe0\xb8\xa0\xe0\xb8\xb2\xe0\xb8\xa9\xe0\xb8\xb2\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2' <====> ภาษาไทย
b'Taqbaylit' <====> Taqbaylit
b'\xd0\xa2\xd0\xb0\xd1\x82\xd0\xb0\xd1\x80\xd1\x87\xd0\xb0/tatar\xc3\xa7a' <====> Татарча/tatarça
b'\xe0\xb0\xa4\xe0\xb1\x86\xe0\xb0\xb2\xe0\xb1\x81\xe0\xb0\x97\xe0\xb1\x81' <====> తెలుగు
b'\xd0\xa2\xd0\xbe\xd2\xb7\xd0\xb8\xd0\xba\xd3\xa3' <====> Тоҷикӣ
b'T\xc3\xbcrk\xc3\xa7e' <====> Türkçe
b'\xd0\xa3\xd0\xba\xd1\x80\xd0\xb0\xd1\x97\xd0\xbd\xd1\x81\xd1\x8c\xd0\xba\xd0\xb0' <====> Українська
b'\xd8\xa7\xd8\xb1\xd8\xaf\xd9\x88' <====> اردو
b'Ti\xe1\xba\xbfng Vi\xe1\xbb\x87t' <====> Tiếng Việt
b'V\xc3\xb5ro' <====> Võro
b'\xe6\x96\x87\xe8\xa8\x80' <====> 文言
b'\xe5\x90\xb4\xe8\xaf\xad' <====> 吴语
b'\xd7\x99\xd7\x99\xd6\xb4\xd7\x93\xd7\x99\xd7\xa9' <====> ייִדיש
b'\xe4\xb8\xad\xe6\x96\x87' <====> 中文
이렇게 보이게 된다. powershell은 utf-8을 지원하지 않아서 깨져 보인다. 마찬가지로 브라우져에서도 몇몇 언어가 꺠져보일 것이다. utf-8을 지원하는 텍스트 에디터에서는 언어가 제대로 보이게 된다.
댓글남기기