Python异常是运行期出错时抛出的对象。不处理就会让程序中断。用 try / except 按类型接管错误,可选的 else 在未出错时执行,finally 无论成败都会跑,适合做清理。需要主动宣告失败时,用 raise 抛出。
先看两类错误
# print(10 / 0) # ZeroDivisionError
# nums = [1, 2]
# print(nums[5]) # IndexError
这些错误若冒到顶层,解释器会打印回溯并结束进程。包进 try 后,可以改成提示信息并继续后面的逻辑。
try / except
不同异常类型可以写多个 except 分支。匹配到哪一个,就只执行那一支:
try:
num = int(input("输入数字: "))
print(10 / num)
except ZeroDivisionError:
print("不能除以 0!")
except ValueError:
print("那不是数字!")输入 0 会走进除零分支。输入字母会在 int(...) 处触发 ValueError。
更宽的兜底
具体类型处理完后,可用 except Exception as e 接住其余常规异常,并通过 e 取出说明文字。尽量少用完全不写类型的裸 except:,它连系统退出类信号也可能吞掉:
try:
result = 10 / int(input("除数: "))
print(result)
except ZeroDivisionError:
print("除数不能是 0")
except Exception as e:
print("出了点问题:", e)else:仅当没有异常
else 紧跟在 except 之后,只有 try 全程成功才会执行,适合放成功之后才该做的步骤:
try:
num = int(input("输入数字: "))
except ValueError:
print("输入无效")
else:
print(f"你输入了 {num}")finally:总会执行
无论是否进过 except,finally 都会跑。关文件、释放锁这类收尾逻辑常放这里:
try 里没报错走 else,报错进 except,finally 无论怎样都执行,适合放关文件、释放资源的清理代码。
try:
f = open("demo.txt", "r")
print(f.read())
except FileNotFoundError:
print("文件不存在")
finally:
print("清理步骤,总会执行")
打开文件失败的常见写法
把读取放进 try,分别处理找不到文件与权限不足。读成功时的后续工作可以放进 else:
try:
with open("config.txt", "r", encoding="utf-8") as f:
content = f.read()
except FileNotFoundError:
print("配置文件不存在,使用默认配置")
content = "default"
except PermissionError:
print("没有读取权限")
else:
print("读取成功,长度", len(content))raise:主动抛出
参数不合法时,不必返回魔法数字,可以直接 raise ValueError(...),由调用方决定如何处理:
def set_age(age):
if age < 0 or age > 150:
raise ValueError(f"年龄不合法: {age}")
return age
try:
set_age(200)
except ValueError as e:
print("捕获:", e)常见误区
- 捕获范围过宽(尤其是裸
except:)会把不该吞掉的错误也藏起来,优先写具体类型。 - 多个
except时,更具体的类型要写在更宽的类型前面,例如ValueError在Exception之前。 except: pass会让故障悄无消失,至少打印或记录异常信息。