unicodedata.digit 和 unicodedata.numeric 有什么区别?

2 python unicode cpython python-3.x python-module-unicodedata

来自unicodedata文档:

unicodedata.digit(chr[, default]) 以整数形式返回分配给字符 chr 的数字值。如果没有定义这样的值,则返回默认值,或者,如果没有给出,则引发 ValueError。

unicodedata.numeric(chr[, default]) 返回分配给字符 chr 的数值作为浮点数。如果没有定义这样的值,则返回默认值,或者,如果没有给出,则引发 ValueError。

有人能解释一下这两个功能之间的区别吗?

在这里,可以阅读这两个函数的实现,但对我来说,与快速查看有什么区别并不明显,因为我不熟悉 CPython 实现。

编辑 1:

一个显示差异的例子会很好。

编辑2:

示例有助于补充@user2357112 的评论和精彩回答:

print(unicodedata.digit('1')) # Decimal digit one.
print(unicodedata.digit('?')) # ARABIC-INDIC digit one
print(unicodedata.digit('¼')) # Not a digit, so "ValueError: not a digit" will be generated.

print(unicodedata.numeric('?')) # Roman number two.
print(unicodedata.numeric('¼')) # Fraction to represent one quarter.
Run Code Online (Sandbox Code Playgroud)

use*_*ica 5

简短的回答:

如果一个字符表示一个十进制数字,那么诸如1, ¹(SUPERSCRIPT ONE), ?(CIRCLED DIGIT ONE), ?(ARABIC-INDIC DIGIT ONE) 之类的东西unicodedata.digit将返回该字符表示为 int 的数字(所有这些示例均为 1) .

如果该字符代表任何数值,那么诸如?(VULGAR FRACTION ONE SEVENTH) 和所有十进制数字示例之类的东西unicodedata.numeric都会将该字符的数值作为浮点数给出。

出于技术原因,最近的数字字符(如(DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ZERO))可能会从unicodedata.digit.


长答案:

Unicode 字符都有一个Numeric_Type属性。此属性可以有 4 个可能的值:Numeric_Type=Decimal、Numeric_Type=Digit、Numeric_Type=Numeric 或 Numeric_Type=None。

引用Unicode 标准,版本 10.0.0,第 4.6 节

Numeric_Type=Decimal 属性值(与 General_Category=Nd 属性值相关)仅限于在十进制基数中使用的那些数字字符,并且已在连续范围内对这些数字字符进行了编码,并具有升序Numeric_Value 的顺序,并以数字零作为范围中的第一个代码点。

因此,Numeric_Type=Decimal 字符是符合其他一些特定技术要求的十进制数字。

Unicode 标准中通过这些属性分配定义的十进制数字不包括某些字符,例如 CJK 表意数字(请参阅表 4-5 中的前十个条目),这些字符未按连续序列进行编码。十进制数字还排除兼容性下标和上标数字,以防止简单的解析器在上下文中误解它们的值。(有关上标和下标的更多信息,请参阅第 22.4 节,上标和下标符号。)传统上,Unicode 字符数据库为这些非连续或兼容数字集赋予数值 Numeric_Type=Digit,以识别它们由数字值组成的事实但不一定满足 Numeric_Type=Decimal 的所有条件。然而,Numeric_Type=Digit 和更通用的 Numeric_Type=Numeric 之间的区别已被证明在实现中没有用。因此,未来可能添加到标准中且不符合 Numeric_Type=Decimal 标准的数字组将简单地分配数值 Numeric_Type=Numeric。

因此,Numeric_Type=Digit 历来用于其他不符合 Numeric_Type=Decimal 技术要求的数字,但他们认为这没有用,并且自 Unicode 6.3 以来,不符合 Numeric_Type=Decimal 要求的数字字符才被指定为 Numeric_Type=Numeric。 0. 例如,Unicode 7.0 中引入的 (DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ZERO) 具有 Numeric_Type=Numeric。

Numeric_Type=Numeric 用于表示数字且不属于其他类别的所有字符,而 Numeric_Type=None 用于不表示数字的字符(或者至少,不要在正常使用下)。

具有非 None Numeric_Type 属性的所有字符都有一个表示其数值的 Numeric_Value 属性。unicodedata.digit将为 Numeric_Type=Decimal 或 Numeric_Type=Digit 的字符返回该值作为 int 值,并将unicodedata.numeric该值作为任何非 None Numeric_Type 的字符返回为浮点数。