在 Python 中,运行期错误以异常对象的形式抛出;若未捕获,程序将中断并打印回溯。使用 try / except 可按类型处理异常;else 在 try 未引发异常时执行,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:,因其可能连 KeyboardInterrupt 等信号一并捕获:
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会使故障静默消失,至少应记录或打印异常信息。
本节说明了 Python 中异常处理各子句的语义与 raise 的用法。下一节介绍迭代器:协议、for 循环及自定义可迭代类。