错误与异常
翻译整理自 Python Tutorial - Errors and Exceptions 与 Built-in Exceptions。
1. 语法错误 SyntaxError
while True
print("oops")
# SyntaxError: expected ':'错误信息形如 File "<stdin>", line 1 并用 ^ 指出出错位置。
2. 异常 Exception
运行时检测到的错误,例如:
10 * (1/0) # ZeroDivisionError
4 + "a" # TypeError
"2" + 2 # TypeError异常栈会输出每层调用、类型与说明。
3. try / except
try:
x = int(input("请输入数字: "))
except ValueError:
print("不是合法整数")
except (TypeError, KeyError):
print("其它异常")
except Exception as e:
print("捕获所有,但不推荐")
else:
print("无异常时执行")
finally:
print("必执行")不要捕获
BaseException,会拦截KeyboardInterrupt。
4. 抛出异常
raise ValueError("n must be positive")
# 重新抛出
try:
...
except SomeError as e:
raise RuntimeError("processing failed") from e5. 自定义异常
派生 Exception 而非 BaseException:
class MyError(Exception):
def __init__(self, message, code):
super().__init__(message)
self.code = code
try:
raise MyError("oops", 500)
except MyError as e:
print(e, e.code)6. 异常链 from
try:
int("abc")
except ValueError as e:
raise RuntimeError("parse failed") from e
# RuntimeError: parse failed
# During handling of the above exception, another exception occurred:
# ValueError: invalid literal for int() with base 10: 'abc'7. finally 与资源
finally 在 try 块退出时必然执行,常用于关闭资源:
f = open("file.txt")
try:
data = f.read()
finally:
f.close()更推荐 with:
with open("file.txt") as f:
data = f.read()8. 自定义上下文管理器
class Timer:
def __enter__(self):
import time
self.start = time.time()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
import time
print("elapsed:", time.time() - self.start)
return False # 不吞异常
with Timer():
sum(range(1_000_000))或用 contextlib.contextmanager:
from contextlib import contextmanager
import time
@contextmanager
def timer():
start = time.time()
try:
yield
finally:
print("elapsed:", time.time() - start)9. 常见异常速查
| 异常 | 触发场景 |
|---|---|
ValueError |
类型对但值非法(如 int("x")) |
TypeError |
类型不对 |
KeyError |
字典 key 不存在 |
IndexError |
序列索引越界 |
AttributeError |
属性不存在 |
FileNotFoundError |
文件未找到 |
StopIteration |
迭代器结束 |
NameError |
名字未定义 |
ZeroDivisionError |
除零 |
KeyboardInterrupt |
用户中断 Ctrl+C |
小结
合理使用异常与 with,能让代码既清晰又安全。