PEP 349 – str()이 유니코드 문자열을 반환할 수 있도록 허용하기
- Author:
- Neil Schemenauer <nas at arctrix.com>
- Status:
- Rejected
- Type:
- Standards Track
- Created:
- 02-Aug-2005
- Python-Version:
- 2.5
- Post-History:
- 06-Aug-2005
- Resolution:
- Python-Dev message
번역·라이선스 안내
이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판
초록
이 PEP는 str() 내장 함수가 유니코드 문자열을 반환할 수 있도록 변경할 것을 제안합니다. 이 변경은 두 문자열 타입 중 어느 쪽으로도 동작하는 코드를 더 쉽게 작성할 수 있게 하며, 일부 기존 코드가 유니코드 문자열을 처리할 수 있게 하기도 합니다. C 함수 PyObject_Str()은 변경 없이 그대로 유지되며, 그 대신 PyString_New() 함수가 추가됩니다.
근거
Python에는 꽤 오래전부터 유니코드 문자열 타입이 있었지만, 아직 널리 사용되지는 않고 있습니다. 문자열 데이터가 str 인스턴스로 표현된다고 가정하는 Python 코드가 많이 있습니다. Python의 장기 계획은 str 타입을 단계적으로 폐지하고 모든 문자열 데이터에 유니코드(unicode)를 사용하는 것입니다. 당연히 원활한 전환 경로가 제공되어야 합니다.
str 인스턴스를 대상으로 작성된 기존 라이브러리를 업그레이드하여, 모든 문자열이 유니코드인 세계에서도 동작할 수 있게 만들어야 합니다. 모든 필수 라이브러리가 이를 지원할 수 있게 되기 전까지는 모든 문자열이 유니코드인 세계로 전환할 수 없습니다. 라이브러리를 한꺼번에 업그레이드하는 것은 실현 가능해 보이지 않습니다. 더 현실적인 전략은 모든 문자열이 str인 현재 환경에서의 동작을 유지하면서, 라이브러리를 하나씩 유니코드 문자열도 처리할 수 있도록 만드는 것입니다.
첫째, 유니코드 인스턴스를 str 인스턴스로 강제 변환하려 하지 않고 그대로 받아들일 수 있는 코드를 작성할 수 있어야 합니다. 이러한 코드를 유니코드 안전(Unicode-safe) 코드라고 부릅시다. 유니코드 안전 라이브러리는 모든 문자열이 유니코드인 세계에서 사용할 수 있습니다.
둘째, str 인스턴스만 주어졌을 때 유니코드 결과를 만들어 내지 않는 코드를 작성할 수 있어야 합니다. 이러한 코드를 str 안정(str-stable) 코드라고 부릅시다. str 안정 라이브러리는 아직 유니코드 안전하지 않은 라이브러리와 애플리케이션에서도 사용할 수 있습니다.
때로는 str 안정적이면서 유니코드 안전하기도 한 코드를 간단하게 작성할 수 있습니다. 예를 들어, 다음 함수는 별다른 처리 없이 그대로 동작합니다:
def appendx(s):
return s + 'x'
유니코드(unicode) 타입은 이 작업을 더 쉽게 만들도록 설계되었으므로 이는 그리 놀라운 일이 아닙니다. 원칙은 str 인스턴스와 유니코드(unicode) 인스턴스가 만나면 그 결과가 unicode 인스턴스가 된다는 것입니다. 한 가지 주목할 만한 어려움은 코드가 객체의 문자열 표현을 필요로 할 때 발생합니다. 이는 전통적으로 str() 내장 함수를 사용하여 수행해 온 작업입니다.
현재의 str() 함수를 사용하면 코드가 유니코드 안전하지 않게 됩니다. str() 호출을 unicode() 호출로 바꾸면 코드가 str 안정적이지 않게 됩니다. str()이 유니코드 인스턴스를 반환할 수 있도록 변경하면 이 문제가 해결됩니다. 추가적인 이점으로, 현재 str()을 사용하기 때문에 유니코드 안전하지 않은 일부 코드가 유니코드 안전하게 됩니다.
명세
다음은 str() 내장 함수의 Python 구현입니다:
def str(s):
"""Return a nice string representation of the object. The
return value is a str or unicode instance.
"""
if type(s) is str or type(s) is unicode:
return s
r = s.__str__()
if not isinstance(r, (str, unicode)):
raise TypeError('__str__ returned non-string')
return r
다음 함수가 C API에 추가되며, 이 함수는 str() 내장 함수와 동등합니다(이상적으로는 PyObject_Str이라는 이름이어야 하지만, 해당 함수를 변경하면 엄청나게 많은 호환성 문제가 발생할 수 있습니다):
PyObject *PyString_New(PyObject *);
참조 구현은 Sourceforge [1]에서 패치 형태로 제공됩니다.
하위 호환성
일부 코드는 str()이 str 인스턴스를 반환하기를 요구할 수 있습니다. 표준 라이브러리에서는 지금까지 그러한 경우가 단 하나만 발견되었습니다. email.header_decode() 함수는 str 인스턴스를 요구하며, email.Header.decode_header() 함수는 인자에 str()을 호출하여 이를 보장하려고 합니다. 이 코드는 “header = str(header)” 줄(헤더 처리 부분)을 다음과 같이 변경하여 수정되었습니다:
if isinstance(header, unicode):
header = header.encode('ascii')
decode_header()는 실제로 문자열이 아니라 바이트 문자열을 대상으로 동작하므로, 이것이 정말 버그인지는 의문입니다. 여기에 유니코드(unicode) 인스턴스를 전달하는 코드 자체가 버그가 있는 것으로 간주될 수 있습니다.
대안
str()을 변경하는 대신 새로운 내장 함수를 추가할 수도 있습니다. 그렇게 하면 하위 호환성 문제가 사실상 전혀 발생하지 않습니다. 그러나 호환성 문제는 드물 것으로 예상되므로, 새로운 내장 함수를 추가하는 것보다 str()을 변경하는 편이 더 나아 보입니다.
str()을 변경하는 대신 basestring 타입이 제안된 동작을 하도록 변경할 수도 있습니다. 그러나 이는 추상 베이스 타입으로서는 혼란스러운 동작이 될 것입니다.
참고 문헌
Copyright
This document has been placed in the public domain.