为什么`'↊'.isnumeric()`false?

ger*_*rit 9 python unicode

根据官方Unicode Consortium代码表,所有这些都是数字:

?   ?   ?   ?   ?   ?   ?   ?   ?   ?   ?   ?   ?   ?   ?   ?
?   ?   ?   ?   ?   ?   ?   ?   ?   ?   ?   ?   ?   ?   ?   ?
?   ?   ?   ?   ?   ?   ?   ?   ?   ?   ?   ?   ?   ?   ?   ?
?   ?   ?   ?   ?   ?   ?   ?   ?   ?   ?   ?
Run Code Online (Sandbox Code Playgroud)

但是,当我要求Python告诉我哪些是数字时,它们都是(偶数?)除了四个:

In [252]: print([k for k in "????????????????????????????????????????????????????????????" if not k.isnumeric()])
['?', '?', '?', '?']
Run Code Online (Sandbox Code Playgroud)

那些是:

  • Ↄ罗马数字逆转了一百
  • ↄ拉丁文小写字母反转C.
  • ↊转数字二
  • ↋转数字三

为什么Python认为那些不是数字?

zwo*_*wol 10

str.isnumeric 对于"具有Unicode数值属性的所有字符",记录为true.

该属性的规范引用是Unicode字符数据库.我们需要的信息可以从http://www.unicode.org/Public/9.0.0/ucd/UnicodeData.txt中挖掘出来,这是撰写本文时的最新版本(2016年末)(警告:1.5MB文本)文件).阅读有点棘手(文档在UAX#44中).我要告诉它的字符条目数字第一,U + 3023杭州三位数字()

3023;HANGZHOU NUMERAL THREE;Nl;0;L;;;;3;N;;;;;
Run Code Online (Sandbox Code Playgroud)

第八个以分号分隔的字段是"数值"属性; 在这种情况下,其值为3,与字符的名称一致.str.isnumeric当且仅当此字段非空时,Python 才是真的.它可以直接使用查询unicodedata.numeric.

所述第三分号分隔的字段是一个两字符代码给人以" 普通类 "; 在这种情况下,"Nl".大多数(但不是全部)具有数值的字符都属于"数字"类别之一(类别代码的第一个字母是N).所有汉族都有例外情况,根据具体情况,可能会或可能不会表示数字; 见UAX#38.

现在,您要询问的角色:

2183;ROMAN NUMERAL REVERSED ONE HUNDRED;Lu;0;L ;;;;;N;;;    ;2184;
2184;LATIN SMALL LETTER REVERSED C     ;Ll;0;L ;;;;;N;;;2183;    ;2183
218A;TURNED DIGIT TWO                  ;So;0;ON;;;;;N;;;    ;    ;
218B;TURNED DIGIT THREE                ;So;0;ON;;;;;N;;;    ;    ;
Run Code Online (Sandbox Code Playgroud)

这些字符没有分配数值,因此Python的行为是正确的 - 如记录的那样.

注意:根据https://docs.python.org/3.6/whatsnew/3.6.html,Python将仅在3.6版本中更新为Unicode 9.0.0; 然而,AFAICT这些角色在相当长的一段时间内没有改变.

("为什么这些字符不具有数值?"是一个只有Unicode联盟才能明确回答的问题;如果您有兴趣,我建议将其提交到其中一个邮件列表.)