2012-02-14 4 views
3

unichr(0x10000)은 없이 cpython을 컴파일 할 때 ValueError으로 실패합니다.파이썬에서 유니 코드 문자열에 보충 코드 포인트

임의의 유니 코드 스칼라 값 또는 코드 포인트를 어떤 종류의 파이썬 인터프리터가 실행되고 있는지에 관계없이 작동하는 unicode 문자열로 변환하는 언어 내장 함수 또는 코어 라이브러리 함수가 있습니까?

+0

저는 이것이 할 수 없다고 확신합니다. 그리고 다른 어떤 사람의 파이썬이 임의의 유니 코드 데이터를 돌릴 수 없다고 믿을 수없는 이유 중 하나이기도합니다. 그러나 이것은 v3.3 릴리스에서 수정 된 것으로 보입니다. 추상적 인 유니 코드를 원한다면 다음 릴리스가 나올 때까지 기다리거나보다 견고한 플랫폼을 사용해야합니다. – tchrist

+0

@ tchrist, 감사합니다. 네. Python3.x를 배워야합니다. 그것은 혼란의 작은 근원을 많이 수정하는 것 같습니다. –

+0

나는 (대부분) @tchrist에 동의하지 않는다. 아래에서 내 대답을 참조하십시오. –

답변

8

예, 여기 있습니다 : 이해하기

>>> unichr(0xd800)+unichr(0xdc00) 
u'\U00010000' 

결정적인 점은 unichr()는 파이썬 인터프리터의 문자열 인코딩에서 단일 코드 단위의 정수로 변환한다는 것입니다. 이 UCS2 [0이 될 수있다 - The Python Standard Library documentation for 2.7.3, 2. Built-in Functions, on unichr()은 돌아 유니 코드 내가 .... 인수의 유효 범위는 파이썬이 구성된 방법에 따라 달라 정수 한 문자의 유니 코드 문자열

읽습니다. .0xFFFF] 또는 UCS4 [0..0x10FFFF]입니다. 그렇지 않으면 ValueError가 발생합니다.

"하나의 문자"에 중점을 두었습니다.이 문자는 "one code unit" in Unicode terms을 의미합니다.

저는 파이썬 2.x를 사용하고 있다고 가정합니다. Python 3.x 인터프리터에는 내장 된 unichr() 함수가 없습니다. 대신 The Python Standard Library documentation for 3.3.0, 2. Built-in Functions, on chr()는 ....

복귀 유니 코드 코드 포인트 정수를 i 문자을 나타내는 문자열을 판독하고, 인수의 유효한 범위는 (기지국 (16)에서 0x10FFFF) 1,114,111 0에서이다.

이제 반환 값은 단일 코드 단위의 문자열이 아닌 지정되지 않은 길이의 문자열입니다. 따라서 파이썬 3.x에서는 chr(0x10000)이 예상대로 동작합니다. "임의의 유니 코드 스칼라 값이나 코드 포인트를 어떤 종류의 파이썬 인터프리터가 실행 중인지 관계없이 작동하는 unicode 문자열로 변환합니다."

하지만 파이썬 2.x로 돌아 가기. unichr()을 사용하여 Python 2.x unicode 객체를 만들고 0xFFFF 이상의 유니 코드 스칼라 값을 사용하는 경우 Python 인터프리터의 unicode 객체 구현을 인식하도록 코드를 커밋하고 있습니다.

당신은 스칼라 값에 unichr()을 시도하는 기능이 인식을 분리 할 수 ​​

ValueError을 포착하고, 해당 UTF-16 서로 게이트 쌍 다시 시도합니다

def unichr_supplemental(scalar): 
    try: 
     return unichr(scalar) 
    except ValueError: 
     return unichr(0xd800 + ((scalar-0x10000)//0x400)) \ 
       +unichr(0xdc00 + ((scalar-0x10000)% 0x400)) 

>>> unichr_supplemental(0x41),len(unichr_supplemental(0x41)) 
(u'A', 1) 
>>> unichr_supplemental(0x10000), len(unichr_supplemental(0x10000)) 
(u'\U00010000', 2) 

하지만 당신은 찾을 수 있습니다 그것에 쉽게 단지 unicode 문자열로이 바이트 string을 수정 UTF-32 바이트 string 4 바이트 UTF-32 값에 스칼라를 변환하고, 디코딩 :

>>> '\x00\x00\x00\x41'.decode('utf-32be'), \ 
... len('\x00\x00\x00\x41'.decode('utf-32be')) 
(u'A', 1) 
>>> '\x00\x01\x00\x00'.decode('utf-32be'), \ 
... len('\x00\x01\x00\x00'.decode('utf-32be')) 
(u'\U00010000', 2) 

코드를 위의 코드는 유니 코드 문자열 용 UTF-16 인코딩을 사용하여 Python 2.6.7에서 테스트되었습니다. 유니 코드 문자열 용 UTF-32 인코딩을 사용하는 Python 2.x 인터프리터에서 테스트하지 않았습니다. 그러나 모든 유니 코드 문자열 구현이있는 Python 2.x 인터프리터에서는 변경되지 않고 작동해야합니다.

+0

좋은 답변입니다. 가장 최근의 파이썬 배포판은 전체적인 "광범위한 빌드"문제를 없앴으며, 이는 또한 큰 도움이됩니다. 이전 릴리스를 실행하는 경우 확실히 "와이드 빌드"를 사용해야합니다. – tchrist

+0

2.x에 대해 정확합니다. 스펙에 대한 지침과 그 차이점에 대한 설명을 보내 주셔서 감사합니다. –

관련 문제