Python에서 encode와 decode: str과 bytes
encode:str에서bytes로decode:bytes에서str로
이때 encoding 방식이 필요하며,
해당 encoding 방식에 따라 동일한 str 객체라도 다른 bytes 객체로 변환된다.
- 참고로,
str객체가 같은 경우엔 Unicode의 codepoint (=코드값)는 같음. - 하지만, encoding방식에 따라 대응되는
bytes객체는 다름.
bytes 대신 bytearray 도 가능.

참고 : Unicode에서의 encoding이란
- Unicode에서 문자열은 일종의 sequence of code points 임. (코드값들의 sequence)
- 이를 저장 및 전송, 또는 메모리에 올리기 위해선 일종의 code unit 으로 변경해야 하며, 이 code unit은 일종의 binary data임.
- utf-8에서 code unit은 1bytes이며, 하나의 글자(code point)를 표현하는데 1,2,3,4 units를 사용 (1글자 표현에 가변길이 units 사용됨)
- utf-16에서 code unit은 2bytes이며, 1과 2개의 unit으로 1글자를 표현함.
- utf-32에서 code unit은 4bytes이며, 1개의 unit으로 1글자를 표현함.
즉, Unicode encoding 이란
code points들의 sequence를,
이에 대응하는bytes객체로 변환하는 것을 의미함.
앞서 말했듯이, Unicode는 여러 개의 encoding 방법(utf-8, utf-16, utf-32 등)을 가짐
Python에서는 이중 기본으로 utf-8 사용.
encode
다음의 눈사람 모양의 글자인 str 객체에서 encode 메서드를 통해 bytes 객체를 얻어냄.
이때 encoding 방식을 argument로 지정함 (없을시 기본값인 utf-8 로 동작.)
snowman_char = "\u2603" # unicode escape sequence. (4자리 혹은 8자리 16진수로 표현)
print(snowman_char) # ☃
print(type(snowman_char)) # <class 'str'>
len(snowman_char) # 1
code_bytes = snowman_char.encode('utf8')
print(type(code_bytes)) # <class 'bytes'>
code_bytes # b'\xe2\x98\x83' , b로 시작하는 literal=bytes literal
cp949나ascii,cp1252,latin-1등의 다양항 encoding을 적용할 수 있음.- 단, 대상
str객체가 해당 encoding에서 지원하지 않는 글자를 포함한 경우,UnicodeEncodeError가 발생함.
위의 "눈사람 글자, ☃"는 ASCII 에는 정의되지 않은 문자이기 때문에 ASCII로 인코딩이 불가함.
code_bytes = snowman_char.encode('ascii')
print(type(code_bytes))
code_bytes
위의 경우 다음의 UnicodeEncodeError가 발생.
---------------------------------------------------------------------------
UnicodeEncodeError Traceback (most recent call last)
<ipython-input-54-2c76e369edaf> in <cell line: 1>()
----> 1 code_bytes = snowman_char.encode('ascii')
2 print(type(code_bytes))
3 code_bytes
UnicodeEncodeError: 'ascii' codec can't encode character '\u2603' in position 0: ordinal not in range(128)
errors 파라메터 설정
encode 에 errors parameter를 이용하여 해당 에러 발생을 방지할 수 있음.
strict: 기본값. 인코딩이 지원하지 않는 글자가 있는 경우 ,UnicodeEncodeError발생시킴.ignore: 인코딩이 지원하지 않는 글자를 무시함. (null문자와 출력은 비슷)replace: 인코딩이 지원하지 않는 글자를?로 치환시킴.backslashreplace: 인코딩이 지원하지 않는 글자를\xNN의 escape sequence로 치환시킴 (N은 16진수 숫자)xmlcharrefreplace: 인코딩이 지원하지 않는 글자를 해당하는 HTML Character Entity로 치환시킴 (&글자이름;). HTML문서에서 사용하는 방식으로 웹브라우저에서 해당 폰트 제공시 깨지지 않고 출력가능.
다음 예제 코드들을 참고.
예제: ignore
code_bytes = snowman_char.encode('ascii',errors='ignore')
print(type(code_bytes))
code_bytes
결과는 다음과 같음.
<class 'bytes'>
b''
예제: replace
code_bytes = snowman_char.encode('ascii', errors='replace')
print(type(code_bytes))
code_bytes
결과는 다음과 같음.
<class 'bytes'>
b'?'
예제 : backslashreplace
code_bytes = snowman_char.encode('ascii', errors='backslashreplace')
print(type(code_bytes))
code_bytes
결과는 다음과 같음.
<class 'bytes'>
b'\\u2603'
예제: xmlcharrefreplace
# HTML character entity를 사용하여 HTML에서 문제없는 문자열 생성.
code_bytes = snowman_char.encode('ascii', errors='xmlcharrefreplace')
print(type(code_bytes))
code_bytes
결과는 다음과 같음.
<class 'bytes'>
b'☃'
decode
encode의 반대로 bytes 객체에서 메서드로 지원됨.
bytes객체로부터str객체를 얻음.- 마찬가지로 encoding방식을 argument로 받을 수 있음.
snowman_char = "\u2603"
code_bytes = snowman_char.encode('utf-8')
print(type(code_bytes)) #bytes
code_bytes
decoded_str = code_bytes.decode('utf8')
print(type(decoded_str)) #str
decoded_str
code_bytes가utf8로 인코딩 된 경우이므로 문제없이 해당하는str객체를 반환함.
결과는 다음과 같음
<class 'str'>
☃
Encoding 방식과 다른 Decoding 방식을 적용시 문제점.
인코딩과 다른 디코딩을 사용하는 경우에 주의가 필요함.
해당 인코딩에서 아예 지원하지 않는 bytes 값에 대해 디코딩을 할 경우,
UnicodeDecodeError가 발생함.
아래 코드의 경우, U+2603 글자를 ASCII는 지원하지 않으므로 에러 발생함.
code_bytes.decode('ascii')
- 앞서
encode경우처럼, errorsparameter에ignorearugment를 넘겨주는 방법으로 해당 에러를 막을 수 있음.
UnicodeDecodeError가 발생하지 않더라도,
다른 인코딩으로 decode할 경우 이상한 문자로 나올 수 있음
(인코딩에서 다른 방식으로 처리한 경우임.)
다음 예를 참고할 것.
code_bytes.decode('cp1252') # 'windows-1252'
code page 1252 인코딩은 서유럽 언어(영어, 스페인어, 프랑스어, 독일어 등)을 지원하는 단일 바이트 문자 인코딩임.
이 경우 결과가 다음과 같음
☃
- 원래 글자가 아닌 다른 글자가 나왔음.
즉, 항상 encode 와 decode 에서 인코딩방식을 같은 것으로 해야한다.
더 읽어보면 좋은 자료들
https://docs.python.org/3/howto/unicode.html
Unicode HOWTO
Release, 1.12,. This HOWTO discusses Python’s support for the Unicode specification for representing textual data, and explains various problems that people commonly encounter when trying to work w...
docs.python.org
https://dsaint31.me/mkdocs_site/CE/ch01/code_for_character/
BME228
Codes for Characters Code 란 특정 형태의 information을 다른 방법으로 표현하는 규칙 또는 해당 규칙으로 표현된 결과물 을 가르킴. 문자를 나타내기 위한 code는 인간이 사용하는 문자 를 일종의 기호 또
dsaint31.me
'Python' 카테고리의 다른 글
| [Python] Module, Package and Library (+ Framework) (1) | 2024.02.03 |
|---|---|
| [Python] Arithmetic, Variables, Types and Assignment (1) | 2024.01.24 |
| [Python] Unicode and Python : Unicode Literal (5) | 2024.01.16 |
| [Python] Binary Bitwise Operations (1) | 2024.01.15 |
| [Python] `struct` 사용하기: bytes 로 C언어 구조체 다루기. (2) | 2024.01.15 |