Дополнительные кодовые точки к строке юникода в python
unichr(0x10000)
терпит неудачу с ValueError
когда cpython компилируется без --enable-unicode=ucs4
,
Существует ли встроенная функция языка или библиотеки ядра, которая преобразует произвольное скалярное значение Юникода или кодовую точку в unicode
Строка, которая работает независимо от того, на каком интерпретаторе Python работает программа?
1 ответ
Да, вот, пожалуйста
>>> unichr(0xd800)+unichr(0xdc00)
u'\U00010000'
Важно понять, что unichr()
преобразует целое число в единицу кода в строковом кодировании интерпретатора Python. Документация по стандартной библиотеке Python для 2.7.3, 2. Встроенные функции, наunichr()
читает,
Вернуть строку Unicode одного символа, чей код Unicode является целым числом i.... Допустимый диапазон для аргумента зависит от конфигурации Python - это может быть либо UCS2 [0..0xFFFF], либо UCS4 [0..0x10FFFF].
ValueError
поднимается иначе.
Я добавил акцент на "один символ", под которым они понимаются как "одна единица кода" в терминах Юникода.
Я предполагаю, что вы используете Python 2.x. Интерпретатор Python 3.x не имеет встроенного unichr()
функция. Вместо этого стандартная библиотека Python для 3.3.0, 2. Встроенные функции, наchr()
читает,
Вернуть строку, представляющую символ, чья кодовая точка Unicode является целым числом i.... Допустимый диапазон для аргумента - от 0 до 1 114 111 (0x10FFFF в базе 16).
Обратите внимание, что возвращаемое значение теперь является строкой неопределенной длины, а не строкой с одной единицей кода. Так в Python 3.x, chr(0x10000)
будет вести себя так, как вы ожидали. Он "преобразует произвольное скалярное значение Юникода или кодовую точку в unicode
строка, которая работает независимо от того, на каком интерпретаторе python запущена программа ".
Но вернемся к Python 2.x. Если вы используете unichr()
создать Python 2.x unicode
объекты, и вы используете скалярные значения 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)
Но вам может оказаться проще просто преобразовать ваши скаляры в 4-байтовые значения UTF-32 в байте UTF-32. string
и декодировать этот байт string
в unicode
строка:
>>> '\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)
Приведенный выше код был протестирован на Python 2.6.7 с кодировкой UTF-16 для строк Unicode. Я не тестировал его на интерпретаторе Python 2.x с кодировкой UTF-32 для строк Unicode. Однако он должен работать без изменений на любом интерпретаторе Python 2.x с любой реализацией строки Unicode.