Получить кодовую точку Unicode символа с помощью Python

В Python API есть ли способ извлечь кодовую точку Unicode для одного символа?

Изменить: если это имеет значение, я использую Python 2.7.


person SK9    schedule 03.09.2011    source источник
comment
+1 .. До прочтения этого понятия не имел, что такое кодовые точки юникода :)   -  person Demian Brecht    schedule 03.09.2011
comment
например для '\ u304f' я хочу '304f'. это то, что будет делать 'ord()'? Да — docs.python.org/library/functions.html#ord   -  person SK9    schedule 03.09.2011
comment
Да, ord("\N{HIRAGANA LETTER KU}") действительно 12367, он же 0x304F. Я бы никогда не использовал числа для символов, как вы, а только имена, как я. Магические числа вредны для вашей программы. Просто подумайте о chr и ord как об обратных функциях друг друга. Это очень просто.   -  person tchrist    schedule 03.09.2011
comment
@tchrist, возможно, стоит отметить, что chr является противоположностью ord в python 3.x, но в python 2.x unichr является обратным ord, поскольку chr работает только для порядковых номеров до 255 в python 2.x.   -  person cryo    schedule 03.09.2011
comment
@David: Да, но я считаю, что это устаревшая система, которая не очень хорошо работает с Unicode — как вы только что продемонстрировали. chr и ord всегда должны были быть обратными, и это была устаревшая ошибка Python 2, которой они иногда не были. Это безумие.   -  person tchrist    schedule 03.09.2011
comment
@tchrist все еще много людей используют python 2.x. Даже в python 3.x все еще есть узкие сборки Unicode (например, большинство сборок Windows для python 3.x являются узкими). , python 2.x обычно отлично работает с Unicode. Однако python 3.0 делает вещи более последовательными, устраняя разницу между str и unicode.   -  person cryo    schedule 03.09.2011
comment
Если c является моей символьной переменной (скажем, она равна ), если я делаю ucp = ord(c), то print ucp я получаю три целых числа, а не одно целое. Как получить одно целое число?   -  person SK9    schedule 03.09.2011
comment
Если это имеет значение, я использую Python 2.7.   -  person SK9    schedule 04.09.2011


Ответы (5)


Если я правильно понял ваш вопрос, вы можете это сделать.

>>> s='㈲'
>>> s.encode("unicode_escape")
b'\\u3232'

Показывает escape-код Unicode в виде исходной строки.

person Keith    schedule 03.09.2011
comment
Если это имеет значение, я использую Python 2.7. - person SK9; 04.09.2011
comment
Что означает b? - person MK Yung; 18.12.2013
comment
@MKYung Этот префикс означает, что это литерал строки байтов. - person Keith; 18.12.2013
comment
Для меня это не работает с символами ASCII: 'a'.encode('unicode_escape') дает a вместо '\\u. (То же самое с u'a'.encode('unicode_escape').) Кроме того, формат отличается, когда вы выходите за пределы базовой многоязычной плоскости: u'????'.encode('unicode_escape') дает '\\U0001f631'. - person ShreevatsaR; 29.12.2013
comment
@ShreevatsaR Попробуйте "a".encode("unicode_escape").hex(), чтобы получить шестнадцатеричное представление в виде str. В качестве альтернативы также подойдет hex(ord("a")). - person imrek; 15.05.2017

Обычно вы просто делаете ord(character), чтобы найти кодовую точку символа. Однако для полноты картины широкие символы в дополнительной многоязычной плоскости Unicode представлены в виде суррогатных пар (т. е. двух единиц кода) в узких сборках Python, поэтому в этом случае мне часто приходилось выполнять этот небольшой обходной путь:

def get_wide_ordinal(char):
    if len(char) != 2:
        return ord(char)
    return 0x10000 + (ord(char[0]) - 0xD800) * 0x400 + (ord(char[1]) - 0xDC00)

Однако в большинстве приложений это редкость, поэтому обычно просто используйте ord().

person cryo    schedule 03.09.2011
comment
Суррогатная пара НЕ состоит из двух символов. Он представляет ОДИН символ. Он состоит из двух кодовых точек. См. кодовую точку и тип кодовой точки в unicode.org/glossary. - person John Machin; 03.09.2011
comment
@JohnMachin: Вы близки, но не совсем: суррогатная пара - это всего лишь одна кодовая точка. Это две кодовые единицы. - person Thanatos; 07.02.2013
comment
@Thanatos: Вы действительно прочитали ссылку, которую я предоставил? Вы дошли до D71 High-surrogate code point: A Unicode code point in the range U+D800 to U+DBFF. и младшего эквивалента D73? - person John Machin; 07.02.2013
comment
@JohnMachin: немного сбивает с толку то, что стандарт использует эту терминологию. Я предполагаю, что в каком-то смысле это кодовые точки — кодовые точки в этих диапазонах зарезервированы для суррогатных пар. Я думаю, стандарт заключается в том, что кодовые точки зарезервированы, вот и все. Примечание. Старшие и младшие суррогатные кодовые точки предназначены для суррогатных кодовых единиц в форме кодировки символов UTF-16. Они не назначены ни одному абстрактному символу. - person Thanatos; 08.02.2013
comment
Моя точка зрения заключалась в том, что суррогатная пара после декодирования представляет собой одну кодовую точку. Есть только две вещи: закодированный поток кодовых единиц UTF-16 или декодированный поток кодовых точек; для суррогатных пар у вас будет 2 в первом и 1 во втором. - person Thanatos; 08.02.2013

Оказывается, сделать это правильно довольно сложно: в Python 2 и Python 3 есть некоторые тонкие проблемы с извлечением кодовых точек Unicode из строки.

Вплоть до Python 3.3 можно было компилировать Python в одном из двух режимов:

  1. sys.maxunicode == 0x10FFFF

В этом режиме строки Unicode Python поддерживают весь диапазон кодовых точек Unicode от U+0000 до U+10FFFF. Одна кодовая точка представлена ​​одним строковым элементом:

>>> import sys
>>> hex(sys.maxunicode)
'0x10ffff'
>>> len(u'\U0001F40D')
1
>>> [c for c in u'\U0001F40D']
[u'\U0001f40d']

Это значение по умолчанию для Python 2.7 в Linux, а также универсально для Python 3.3 и более поздних версий во всех операционных системах.

  1. sys.maxunicode == 0xFFFF

В этом режиме строки Unicode Python поддерживают только диапазон кодовых точек Unicode от U+0000 до U+FFFF. Любые кодовые точки от U+10000 до U+10FFFF представлены парой строковых элементов в кодировке UTF-16:

>>> import sys
>>> hex(sys.maxunicode)
'0xffff'
>>> len(u'\U0001F40D')
2
>>> [c for c in u'\U0001F40D']
[u'\ud83d', u'\udc0d']

Это значение по умолчанию для Python 2.7 в macOS и Windows.

Эта разница во время выполнения делает написание модулей Python для манипулирования строками Unicode как сериями кодовых точек довольно неудобно.

Модуль кодовых точек

Чтобы решить эту проблему, я добавил новый модуль codepoints в PyPI:

https://pypi.python.org/pypi/codepoints/1.0

Этот модуль решает проблему, предоставляя API для преобразования строк Unicode в списки кодовых точек и из них, независимо от базовой настройки для sys.maxunicode::

>>> hex(sys.maxunicode)
'0xffff'
>>> snake = tuple(codepoints.from_unicode(u'\U0001F40D'))
>>> len(snake)
1
>>> snake[0]
128013
>> hex(snake[0])
'0x1f40d'
>>> codepoints.to_unicode(snake)
u'\U0001f40d'
person Ben Hamilton    schedule 16.02.2017
comment
Здравствуйте, я пытаюсь использовать кодовые точки со смещением en.wikipedia.org/wiki/Regional_Indicator_Symbol на сделать флаги разных стран в Python. Вот реализация javascript: github.com/thekelvinliu/ country-code-emoji/blob/ Как использовать codepoints.to_unicode(x) в измененных кодах, которые были смещены соответствующими буквами базового флага? - person thadk; 06.03.2017
comment
ОБНОВЛЕНИЕ: разобрался, to_unicode нужен как минимум из двух кортежей. - person thadk; 06.03.2017
comment
@thadk, рад, что вы это поняли, но не могли бы вы поделиться со мной первым фрагментом кода, который вы попробовали? Мне интересно, что не сработало. - person Ben Hamilton; 07.03.2017

питон2

>>> print hex(ord(u'人'))
0x4eba
person lookinghong    schedule 04.07.2019

person    schedule
comment
Конечно, вместо этого он может распечатать u'e' 101 и u'\u0301' 769 в конце... - person Dietrich Epp; 03.09.2011
comment
Похоже, что 'ord()' делает то, что я хочу: docs.python.org/library /functions.html#ord. Спасибо. - person SK9; 03.09.2011
comment
Если 'c' - моя символьная переменная (скажем, она равна 'あ'), если я делаю ucp = ord(c), затем print ucp, я получаю три целых числа, а не одно целое. Как получить одно целое число? - person SK9; 03.09.2011
comment
Как вы получили あ в переменной? Если это литерал в исходном коде, убедитесь, что исходный файл имеет соответствующий набор кодировок. В противном случае задайте новый вопрос и опубликуйте более подробный код. - person Karl Knechtel; 03.09.2011
comment
Если это имеет значение, я использую Python 2.7. - person SK9; 04.09.2011
comment
важно отметить, что он не работает в более старых версиях ipython (например, в 0.10.2, который есть в Debian Squeeze). В обычном питоне (например 2.6.*) работает нормально - person Michel Samia; 22.08.2012
comment
Я попробовал этот же пример с བཞིན, но он не работает. У вас есть идея, как я могу получить тот же результат, что и с cafe в двухбайтовых наборах символов? то есть мой случай такой же, как комментарий OP выше. Вы можете проверить, используя приведенный выше пример кода от Майка Грэма, но используйте символы, которые я предоставил. - person mikkokotila; 02.01.2018
comment
@mikkokotilaВы не упомянули свою платформу или версию Python. К сожалению, детали различаются. В Python 2, если вы используете u"བཞིན" (а не "བཞིན", вы не столкнетесь с проблемами из-за того, что символы больше одного байта - однако он будет рассматривать это как четыре символа, причем ི и ཞ считаются двумя разными Я не знаю, включает ли Unicode такие комбинации для тибетского языка, как для латыни с акцентом (где существуют как é с одной кодовой точкой (u'\xe9'), так и é с двумя кодовыми точками (u'e\u0301'). Извините, я не могу быть более полезным. - person Mike Graham; 06.01.2018