Python 数字字符判断:isdigit 已经通过,为什么 int 仍然不接受上标二
数量输入先通过 isdigit,再交给 int,上标二却在第二步报错。原因是“字符属于数字类别”和“整个字符串符合整数语法”回答不同问题。Unicode 还收录了分数、上标以及多种文字系统里的数字,三个常见判断方法的范围并不一样。
下面使用六组短字符串,逐项检查分类结果和实际转换。保存为 UTF-8 的 demo.py,运行 python demo.py。最后给出一个明确只接受一到六位ASCII数字的数量入口,避免让工具名称替业务决定允许什么输入。
AI模型生成概念示意:普通数字、上标数字和分数字符落在层层扩大的分类范围里;图形仅解释集合关系,不是字符数据库截图。
cases = [
("ascii", "2", (True, True, True), "2"),
("arabic", "٢", (True, True, True), "2"),
("superscript", "²", (False, True, True), "ValueError"),
("fraction", "½", (False, False, True), "ValueError"),
("signed", "-2", (False, False, False), "-2"),
("empty", "", (False, False, False), "ValueError"),
]
for name, text, flags, expected in cases:
actual = (text.isdecimal(), text.isdigit(), text.isnumeric())
assert actual == flags
try:
converted = str(int(text))
except ValueError:
converted = "ValueError"
assert converted == expected
print(name + ":", actual, "int=" + converted)
def parse_count(text):
if not (isinstance(text, str) and 1 <= len(text) <= 6
and text.isascii() and text.isdecimal()):
raise ValueError("expected 1 to 6 ASCII digits")
return int(text)
assert parse_count("002") == 2
for invalid in ("٢", "²", "-2", "", "1234567", 2):
try:
parse_count(invalid)
except ValueError:
pass
else:
raise AssertionError("invalid input accepted")
print("strict ASCII input: 6 invalid cases rejected")三个判断范围逐层扩大
ascii 和 arabic 两行都打印 (True, True, True),转换结果都是二。第二个样本是 U+0662,属于Unicode十进制数字;isdecimal并不限定键盘上的0到9。若协议只允许ASCII,单独使用它仍然比协议宽。
superscript 行为 (False, True, True),int=ValueError;fraction 行为 (False, False, True),同样转换失败。上标二属于digit类别,却不是普通十进制位;二分之一字符具有数值属性,因此isnumeric能认出,但int不会把它自动解释成一个分数。
字符分类不是完整数值解析器
signed 行三个判断都为False,int却成功得到负二。负号不是数字字符,但它可以出现在合法整数文本中。空串三个判断也都为False,转换失败。把两个方向的反例一起保留,能避免误以为某个is方法与int接受范围完全一致。
这些方法检查的是整串每个字符是否属于相应类别,并要求至少有一个字符;它们不会检查小数点、指数或正负号组成的数值语法。若接口允许带符号整数,可以按明确语法解析并处理失败;若是商品编号或邮编,即使全是数字,也可能应该一直保存为文本。
把接口允许的范围写在入口
parse_count先检查字符串类型与长度,再同时要求ASCII和十进制数字。六个拒绝样本覆盖非ASCII数字、上标、负号、空串、长度超限以及传入整数对象;最后一行确认它们全部被拒绝。这个约定刻意不接受空格和符号,读者应按自己的接口要求调整,而非直接视为所有数量字段的通用标准。
示例接受002并返回二,这会失去前导零。如果前导零代表固定宽度标识,应返回验证后的原字符串。业务上限也需单独判断:一到六位只是文本长度约束,不证明某个数值适合库存、页数或重试次数。
不要为了让int成功,先无条件删除不认识的字符;那可能把无效输入变成另一个有效数。保留原输入、拒绝原因与适用的字符规则,才能让调用者知道需要修正什么,也便于升级运行时后用同一组样本核对行为。
资料核对日期:2026年10月2日。示例在本地 Python 3.12.14 实际执行,全部断言通过;输出对应文中固定输入。


