# Strings (Python)

파이썬과 GTK+에서 문자열을 다루는 방법을 설명합니다.
Sebastian Pölsterl
sebp@k-d-w.org 2011
Marta Maria Casetti
mmcasetti@gmail.com 2012
조성호
shcho@gnome.org 2017-2019.

# 문자열

그놈은 프로그램을 작성할 때 파이썬 3 활용을 강력하게 권장합니다!

# 파이썬 2의 문자열

파이썬 2에서는 문자열을 표현하는 두가지 다른 객체 형식이 있는데 `str`과 `unicode`가 있습니다. `unicode` 인스턴스는 유니코드 문자열을 표현할 때 활용하며, `str`형식은 인코딩한 문자열 바이트를 표현할 때 활용합니다. 내부적으로 파이썬에서는 파이썬 인터프리터를 어떻게 컴파일했느냐에 따라 유니코드 문자열을 16비트 내지는 32비트 정수로 표현합니다.

>>> unicode_string = u"Fu\u00dfb\u00e4lle" >>> print unicode_string Fußbälle

유니코드 문자열은 `unicode.encode()`로 8비트 문자열로 바꿀 수 있습니다. 파이썬의 8비트 문자열은 주어진 인코딩으로 문자열을 해석하는 `str.decode()` 메서드가 있습니다(그 말인 즉슨, `unicode.encode()`의 반대 개념입니다):

>>> type(unicode_string) <type 'unicode'> >>> unicode_string.encode("utf-8") 'Fu\xc3\x9fb\xc3\xa4lle' >>> utf8_string = unicode_string.encode("utf-8") >>> type(utf8_string) <type 'str'> >>> unicode_string == utf8_string.decode("utf-8") True

불행하게도 파이썬 2.x에서는 8비트 문자열에 7비트(아스키) 바이트가 들어가지만 ASCII 값이 아닌 경우 UnicodeDecodeError가 발생하므로, `unicode`와 `str` 의 혼용을 허용하지 않습니다.

# 파이썬 3의 문자열

파이썬 3.0 부터는 모든 문자열을 `str` 형식의 인스턴스에 유니코드로 저장합니다. 다른 방식으로 인코딩한 문자는 바이트 타입의 인스턴스에 이진 데이터로 표현합니다. 개념적으로 `str`은 텍스트를 참조하고 bytes는 데이터를 참조합니다. `str` 형식에서 `bytes` 형식으로 변환할 때는 `encode()` 함수를, `bytes` 형식에서 `str` 형식으로 변환할 때는 `decode()` 함수를 사용하십시오.

게다가, 더이상 유니코드 문자열과 인코딩 문자열을 혼용할 수 없는데, 결과적으로 `TypeError`가 발생하기 때문입니다:

>>> text = "Fu\u00dfb\u00e4lle" >>> data = b" sind rund" >>> text + data Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: Can't convert 'bytes' object to str implicitly >>> text + data.decode("utf-8") 'Fußbälle sind rund' >>> text.encode("utf-8") + data b'Fu\xc3\x9fb\xc3\xa4lle sind rund'

# GTK+의 유니코드

GTK+에서는 UTF-8 인코딩 문자열을 모든 텍스트에 사용합니다. 무슨 이야기냐면, 문자열을 반환하는 메서드를 호출하면 `str` 형식 인스턴스를 받습니다. 하나 이상의 문자열을 받는 메서드에도 동일하게 적용하며, UTF-8로 인코딩해야합니다. 그러나 PyGObject에서는 인자에 데이터가 들어오면 어떤 유니코드 인스턴스든 문자열로 자동으로 바꿔줍니다:

>>> from gi.repository import Gtk >>> label = Gtk.Label() >>> unicode_string = u"Fu\u00dfb\u00e4lle" >>> label.set_text(unicode_string) >>> txt = label.get_text() >>> type(txt) <type 'str'>

게다가:

>>> txt == unicode_string

는 `False`값을 반환하며, `__main__:1: UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal` (`Gtk.Label.get_text()` 는 항상 `str` 인스턴스를 내보내기 때문에, `txt` 와 `unicode_string` 은 다릅니다) 경고를 내보냅니다..

`gettext`로 프로그램을 국제화할 경우 특히 더 중요합니다. `gettext`에서 모든 언어에 대해 항상 UTF-8로 인코딩한 8비트 문자열을 반환하는지 확인하셔야합니다.

일반적으로 GTK+ 프로그램 전체에서 `unicode` 객체를 안 쓰는게 좋으며, GTK+가 `unicode`를 완전히 통합하지 않았기에, UTF-8로 인코딩한 `str` 객체만 씁니다.

문자열 인코딩은 파이썬 3.x에서 좀 더 일관성이 있는데 PyGObject는 메서드로 문자열을 넘겨주거나 메서드에서 문자열을 반환할 때 자동으로 UTF-8로/부터 인코딩/디코딩을 처리합니다. 문자열, 텍스트는 항상 `str` 인스턴스로만 표현합니다.

# 참고 자료

문자열 다루기 - Python GTK+ 3 따라하기 지침서