str.isdigit()仅识别unicode数字字符(如'0'–'9'、全角数字、上/下标),不认符号、小数点、空格、罗马数字或汉字数字;判断能否转数字应使用try/except。

str.isdigit() 为什么有时返回 False 却明明全是“数字”
因为 isdigit() 只认 Unicode 中被归类为“数字字符(Nd 类)”的码点,比如 '0'–'9'、全角数字 '0'–'9'、上标 '²'、下标 '₅'。但它**不认带符号的字符串**(如 '-1'、'+3'),也不认小数点、逗号、千分位符,甚至不认罗马数字 'Ⅴ' 或汉字数字 '三'——这些全会返回 False。
常见误用场景:用户输入一个“看起来是整数”的字符串(比如从表单或 CSV 读进来的 ' 123 ' 或 '12.0'),直接调用 isdigit() 判断是否为数字,结果意外失败。
- 空字符串
''→False - 含空格
'123 '或' 123'→False - 负数
'-123'、小数'12.3'、科学计数'1e3'→ 全部False - 全角数字
'123'→True(这是它和isdecimal()的关键区别)
isnumeric() 比 isdigit() 更宽泛,但依然不是“能转成数字”
isnumeric() 包含 isdigit() 的所有字符,还额外支持更多 Unicode 数值型字符,比如分数 '¾'、带圆圈的数字 '①'、汉字数字 '一'、甚至某些带修饰的数值符号(如 '⁰')。但它**仍然拒绝任何非数值字符**,包括符号、空白、小数点、字母。
典型陷阱:看到 '一' 返回 True 就以为能用 int() 转,结果抛 ValueError;或者误以为 '12.3' 也能过,其实照样返回 False。
-
'½'、'Ⅳ'、'㊀'→True -
'12.3'、'-5'、'1,000'→False -
isnumeric()对空格、制表符、换行符全部敏感 →False
真正想判断“能否安全转成 int/float”,别只靠 isdigit/isnumeric
这两个方法本质是做 Unicode 字符分类检查,不是类型校验。如果你的目标是“这个字符串能不能喂给 int() 或 float() 不报错”,最直白可靠的方式就是**用异常捕获来试转**:
def is_int_str(s):
try:
int(s)
return True
except ValueError:
return False
def is_float_str(s):
try:
float(s)
return True
except ValueError:
return False
注意这会接受 ' 123 '(int() 和 float() 自动 strip)、'+42'、'-0x1A'(十六进制)、'1e2' 等合法字面量,但拒绝 '12.3.4'、'inf'(除非你明确要支持)、'NaN'。
- 如果需严格限制为十进制整数(不含前导零、不含符号),先
s.strip()再结合isdigit()+ 长度判断更稳妥 - 若来自不可信输入(如 Web 表单),用
try/except比正则更清晰,也避免正则漏掉 Unicode 数字变体 -
float()会接受'inf'和'nan',如需排除,得额外检查math.isfinite(float(s))
性能差异小,但语义不能混用
在大多数应用中,isdigit()、isnumeric() 和 try: int() 的性能差距可以忽略(百万次调用差几毫秒)。真正关键的是:它们回答的是**不同问题**。
-
isdigit()→ “这个字符串是不是由纯数字字符组成?”(Unicode 层面) -
isnumeric()→ “这个字符串在 Unicode 中是否表示一个数值?”(更广的符号集合) -
try: int(s)→ “Python 解析器能否把它当作整数字面量处理?”(语法+语义层面)
选哪个,取决于你真正关心的边界在哪里——是字符形状?是语言学上的“数”?还是运行时能否参与计算?混淆这三者,是很多看似“奇怪”的 False 返回值的根源。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











