错误与异常

翻译整理自 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 e

5. 自定义异常

派生 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,能让代码既清晰又安全。