Unicode下标和标识符中的上标,为什么Python会考虑XU ==Xᵘ==Xᵤ?

时间:2018-01-23 15:08:29

标签: python unicode syntax identifier

Python允许使用unicode标识符。我定义了Xᵘ = 42,期望XUXᵤ产生NameError。但实际上,当我定义Xᵘ时,Python(默默地?)将Xᵘ转换为Xu,这让我觉得有些单调的事情要做。为什么会这样?

>>> Xᵘ = 42
>>> print((Xu, Xᵘ, Xᵤ))
(42, 42, 42)

2 个答案:

答案 0 :(得分:12)

Python将所有标识符转换为NFKC normal form;来自参考文档的Identifiers section

  

解析时,所有标识符都转换为正常格式NFKC;标识符的比较基于NFKC。

超级和下标字符的NFKC形式是小写u

>>> import unicodedata
>>> unicodedata.normalize('NFKC', 'Xᵘ Xᵤ')
'Xu Xu'

所以最后,你只拥有一个标识符Xu

>>> import dis
>>> dis.dis(compile('Xᵘ = 42\nprint((Xu, Xᵘ, Xᵤ))', '', 'exec'))
  1           0 LOAD_CONST               0 (42)
              2 STORE_NAME               0 (Xu)

  2           4 LOAD_NAME                1 (print)
              6 LOAD_NAME                0 (Xu)
              8 LOAD_NAME                0 (Xu)
             10 LOAD_NAME                0 (Xu)
             12 BUILD_TUPLE              3
             14 CALL_FUNCTION            1
             16 POP_TOP
             18 LOAD_CONST               1 (None)
             20 RETURN_VALUE

上面编译的字节码的反汇编表明标识符在编译期间已经标准化;这在解析期间发生,在创建编译器用于生成字节码的AST(抽象解析树)时,任何标识符都被标准化。

标识符被规范化以避免许多潜在的“看似相似”的错误,否则您最终可能会同时使用find()(使用U+FB01 LATIN SMALL LIGATURE FI字符后跟ASCII nd字符)和find(),并想知道为什么你的代码有错误。

答案 1 :(得分:2)

Python,从3.0版开始,支持非ASCII标识符。当使用NFKC规范化转换解析标识符时,标准化值相同的任何标识符都被视为相同的标识符。

有关详细信息,请参阅PEP 3131。 https://www.python.org/dev/peps/pep-3131/