Я бавився з ідентифікаторами Unicode і натрапив на це:
>>> 𝑓, x = 1, 2
>>> 𝑓, x
(1, 2)
>>> 𝑓, f = 1, 2
>>> 𝑓, f
(2, 2)
Що тут відбувається? Чому Python замінює об’єкт, на який посилається 𝑓
, але лише іноді? Де описана така поведінка?
Я бавився з ідентифікаторами Unicode і натрапив на це:
>>> 𝑓, x = 1, 2
>>> 𝑓, x
(1, 2)
>>> 𝑓, f = 1, 2
>>> 𝑓, f
(2, 2)
Що тут відбувається? Чому Python замінює об’єкт, на який посилається 𝑓
, але лише іноді? Де описана така поведінка?
a, a = 1, 2; a, a
. Це не має нічого спільного з f
або 𝑓
.
𝑓 = 3; f
було б достатньо.
Відповіді:
PEP 3131 - Зазначається підтримка ідентифікаторів, що не належать до ASCII
Усі ідентифікатори перетворюються в нормальну форму NFKC під час синтаксичного аналізу; порівняння ідентифікаторів базується на NFKC.
Ви можете використовувати unicodedata
для перевірки конверсій:
import unicodedata
unicodedata.normalize('NFKC', '𝑓')
# f
що означало б, що '𝑓'
перетворюється на 'f'
аналіз. Провідний до очікуваного:
𝑓 = "Some String"
print(f)
# "Some String"
π
ідентифікатор Python, який відрізняється від p
просто чудового. Якщо я правильно розумію, складання NFK * стосується символів, які, як вважали люди Юнікоду, мали б бути однаковими, але їх не можна об’єднати через зворотну сумісність із деякими застарілими кодуваннями.
Ось невеликий приклад, щоб показати, наскільки жахлива ця "особливість":
𝕋𝐡ᵢ𝔰_f𝔢𝘢𝚝𝓊ᵣₑ_𝕤ₕ𝔬𝔲𝖑𝔡_dₑ𝕗ᵢ𝘯i𝘵𝚎ℓy_𝒷𝘦_𝐚_𝚋ᵘg = 42
print(T𝗵ℹ𝚜_𝒇e𝖆𝚝𝙪ᵣe_ₛ𝔥º𝓾𝗹𝙙_𝚍e𝒇ᵢ𝒏ⁱtᵉ𝕝𝘆_𝖻ℯ_𝔞_𝖇𝖚𝓰)
# => 42
Спробуйте в Інтернеті! (Але, будь ласка, не використовуйте його)
І як згадував @MarkMeyer, два ідентифікатори можуть бути різними, хоча вони виглядають однаково ("КИРИЛІЧНА ВЕЛИКА БУКВА А" та "ЛАТИННА ВЕЛИКА БУКВА А")
А = 42
print(A)
# => NameError: name 'A' is not defined
А = 42; print(A)
-> "NameError: ім'я 'A' не визначено"
𝑓=1
f=2
print(𝑓)