valueerror 是类型正确但值非法,如 int("abc");typeerror 是类型不支持该操作,如 "hello" + 42;判断依据是错误关键词和实际类型验证,需精准捕获而非泛用 except exception。

ValueError 是“类型对但值不对”
当你传入的参数类型没错,但内容不合逻辑或超出范围,就会触发 ValueError。它不怪你用错类型,而是怪你“用对了类型却给了错的值”。
常见场景包括:
-
int("abc")—— 字符串是合法类型,但内容不是数字 -
[1, 2, 3].index(4)—— 列表支持index(),但 4 不在其中 -
math.sqrt(-1)—— 参数是 float,但负数在实数域无定义 -
datetime.date(2026, 2, 30)—— 2 月没有 30 日,类型全对,值非法
这类错误往往发生在数据校验、解析、数学运算或内置函数的语义约束环节。修复重点是检查输入值是否落在业务或函数预期范围内,而不是改类型。
TypeError 是“类型本身就不该这么用”
TypeError 表示操作对象的类型根本不支持当前行为,属于“类型层面的不兼容”。它不管值是什么,只看能不能做这件事。
典型例子有:
-
"hello" + 42——+对 str 和 int 没定义 -
len(42)—— 整数没有长度概念,len()只接受序列或映射类型 -
5()—— 把整数当函数调用,而int不可调用 -
{1, 2}[0]—— set 不支持索引,[]操作不适用于该类型
这类错误通常暴露在接口误用、类型混淆或动态调用时。修复方向是确认操作是否适用于该类型,必要时做显式转换(比如 str(42))或换用合适的方法。
怎么快速判断该 catch 哪个异常?
遇到报错先看错误信息里的关键词,再结合上下文判断根源:
- 报错含
invalid literal、not in list、math domain error、day is out of range→ 大概率是ValueError - 报错含
can only concatenate、object is not callable、has no len()、unsubscriptable→ 基本锁定TypeError - 不要只看变量名或函数名,要盯住被操作的对象实际类型:用
type(x)或isinstance(x, ...)验证,而不是假设 - 同一个函数可能既抛
TypeError又抛ValueError,比如int("12.5")是ValueError(格式不对),而int([1,2])是TypeError(类型不支持)
写 except 时别偷懒只写 except Exception:,否则会掩盖真正的类型问题,调试成本翻倍。
自定义函数里怎么合理 raise 这两个异常?
主动抛异常是为了让调用方明确知道错在哪,所以选型要精准:
- 如果参数类型正确,但值违反业务规则(如负年龄、超长用户名、非法状态码),raise
ValueError - 如果参数类型根本不能参与该操作(如传了 list 给只接受 str 的字段校验函数),raise
TypeError - 避免在类型检查后又 raise
ValueError:比如先用isinstance(x, str)确认是字符串,再检查长度,那后续所有异常都应是ValueError - 文档里写清楚每个参数的类型要求和取值范围,比异常提示更重要
很多人卡在“值错”和“类型错”的边界上,比如 json.loads(None) 报的是 TypeError(因为 None 不是字符串),而 json.loads("abc") 报的是 JSONDecodeError(继承自 ValueError)。这种细节得靠读源码或实测确认,不能凭感觉猜。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











