【问题标题】:str.isdigit() behaviour when handling strings处理字符串时的 str.isdigit() 行为
【发布时间】:2021-11-15 11:42:47
【问题描述】:

假设如下:

>>> square = '²'      # Superscript Two (Unicode U+00B2)
>>> cube  = '³'       # Superscript Three (Unicode U+00B3)

奇怪的是:

>>> square.isdigit()
True
>>> cube.isdigit()
True

好的,让我们将这些“数字”转换为整数:

>>> int(square)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: '²'
>>> int(cube)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: '³'

哎呀!

有人能解释一下我在处理字符串时应该从str.isdigit() 方法中得到什么行为吗?

【问题讨论】:

标签: python python-3.x


【解决方案1】:

str.isdigit 不声称与 int 的可解析性有关。它报告了一个简单的 Unicode 属性,它是十进制字符还是某种数字:

str.isdigit()

如果字符串中的所有字符都是数字并且至少有一个字符,则返回True,否则返回False。数字包括十进制字符和需要特殊处理的数字,例如兼容性上标数字。这涵盖了不能用于​​形成以 10 为底的数字的数字,例如 Kharosthi 数字。形式上,数字是具有属性值 Numeric_Type=Digit 或 Numeric_Type=Decimal 的字符。

简而言之,str.isdigit 对于检测有效数字毫无用处。检查给定字符串是否为合法整数的正确解决方案是在其上调用int,如果它不是合法整数,则捕获ValueError。您所做的任何其他事情都会(严重地)重新发明int() 中的实际解析代码执行的相同测试,那么为什么不让它首先完成工作呢?

旁注:您错误地使用了术语“utf-8”。 UTF-8 是一种特殊的 Unicode 编码方式,仅适用于原始二进制数据。 Python 的str 是一种“理想化”的Unicode 文本类型;它没有编码(在引擎盖下,它被存储为 ASCII、latin-1、UCS-2、UCS-4 和可能还有 UTF-8 之一,但在 Python 层中,除了间接测量之外,这些都不可见比如sys.getsizeof,它只通过让你看到字符串消耗了多少内存来暗示底层编码)。您所说的字符是 ASCII 范围以上的简单 Unicode 字符,它们不是专门的 UTF-8。

【讨论】:

  • 我不知道isdigit 这样做。这对isnumeric 是否成立?我将不得不为此 grep 我的 github org 并在明天修复它。
  • @flakes: isnumeric 对于检测字符串是否代表数字也没什么用。它测试 Unicode 属性 Numeric_Type=Digit、Numeric_Type=Decimal 或 Numeric_Type=Numeric 的字符。
  • @flakes: isnumeric 更糟;它返回True 用于所有isdigit 封面,以及第三类Numeric_Type=Numericisdecimal 似乎是最严格的测试(事实上,'²'.isdecimal() 返回 False,与 isdigitisnumeric 不同),因此它让您更接近构成有效 int 的内容,但同样, “这是合法的int?”的正确解决方案是“调用int() 并在它失败时捕获ValueError”;对字符串属性的预检查要么过于严格(-2 不会通过这些测试,但 int() 可以解析它)要么过于宽松(允许 ² 等)。
  • 别忘了isalnum 也将是True
  • 请注意,Numeric_Type=Digit 不再用于新字符,因此 isdigit 执行的测试现在比以前更有用 - 以前会收到 Numeric_Type=Digit 现在的新字符接收 Numeric_Type=Numeric。见Unicode Standard 14.0 chapter 4.6
猜你喜欢
  • 1970-01-01
  • 2017-08-21
  • 1970-01-01
  • 2012-07-20
  • 2021-07-21
  • 1970-01-01
  • 1970-01-01
  • 2014-08-24
  • 1970-01-01
相关资源
最近更新 更多