Как блокнот jupyter анализирует имена переменных в юникоде и почему я получаю ошибку? - PullRequest
2 голосов
/ 16 октября 2019

Одна вещь, которая мне очень нравится работать в Python в блокноте jupyter, это то, что я могу использовать некоторые символы Юникода для именования своих переменных. Например, чтобы использовать греческие буквы, я набираю \alpha, за которым следует tab, и я получаю α.

. Я столкнулся с неожиданным поведением при использовании жирного шрифта T, \bfT, за которым следует tab, которыйрезультаты в ?.

Эксперимент следующий. Внутри ячейки (под управлением Python 3) введите:

T = 1
? = 2
print(T)  # prints 2 

К моему удивлению, вторая строка переназначает переменную T, но я ожидаю, что она будет отличаться от ?. Может кто-нибудь объяснить, в чем подвох с использованием Unicode?

Не знаю, помогает ли это, но в качестве другого эксперимента я вижу, что те же два символа, что и строки, на самом деле разные

'T'.encode('utf8'), '?'.encode('utf8')  # (b'T', b'\xf0\x9d\x90\x93')

Как ноутбук обрабатывает мои имена переменных?

1 Ответ

3 голосов
/ 16 октября 2019

Это поведение определено в спецификации языка Python для идентификаторов (имен переменных). https://docs.python.org/3/reference/lexical_analysis.html#identifiers

2.3. Идентификаторы и ключевые слова

Идентификаторы (также называемые именами) описываются следующими лексическими определениями.

Синтаксис идентификаторов в Python основан на стандартном приложении Unicode UAX-31, с уточнениеми изменения, как определено ниже;подробнее см. также PEP 3131.

[...]

Все идентификаторы преобразуются в обычную форму NFKC при анализе; сравнение идентификаторов основано на NFKC.

Мы можем подтвердить, что T и equivalent эквивалентны в NFKC, используя стандартный модуль unicodedata .

>>> import unicodedata
>>> unicodedata.normalize('NFKC','?') == 'T'
True

Поэтому вам следует избегать использования подобныхсимволы Юникода в той же области, что и уникальные имена переменных.

Но все еще есть много уникальных символов Юникода, которые можно безопасно использовать в идентификаторах:

>>> unicodedata.normalize('NFKC','?λ')
'?λ'
...