我在玩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
就足够了。
Answers:
解析时,所有标识符都转换为标准形式NFKC;标识符的比较基于NFKC。
您可以unicodedata
用来测试转换:
import unicodedata
unicodedata.normalize('NFKC', '𝑓')
# f
这表示在解析中将'𝑓'
转换为'f'
。导致预期:
𝑓 = "Some String"
print(f)
# "Some String"
π
作为Python标识符,您可以拥有与众不同的标识符p
。如果我理解正确,则NFK *折叠与Unicode人们认为应该以相同的字符开头的字符有关,但由于与某些旧编码的向后兼容性,它们无法合并。
这是一个小示例,仅用于说明此“功能”有多可怕:
𝕋𝐡ᵢ𝔰_f𝔢𝘢𝚝𝓊ᵣₑ_𝕤ₕ𝔬𝔲𝖑𝔡_dₑ𝕗ᵢ𝘯i𝘵𝚎ℓy_𝒷𝘦_𝐚_𝚋ᵘg = 42
print(T𝗵ℹ𝚜_𝒇e𝖆𝚝𝙪ᵣe_ₛ𝔥º𝓾𝗹𝙙_𝚍e𝒇ᵢ𝒏ⁱtᵉ𝕝𝘆_𝖻ℯ_𝔞_𝖇𝖚𝓰)
# => 42
在线尝试!(但是请不要使用它)
而且,正如@MarkMeyer所提到的,即使两个标识符看起来相同,它们也可能是不同的(“西里尔大写字母A”和“拉丁大写字母A”)
А = 42
print(A)
# => NameError: name 'A' is not defined
А = 42; print(A)
->“ NameError:未定义名称'A'”
𝑓=1
f=2
print(𝑓)