1. 代码的“意外”:异常是躲不开的 🤕

关键字

:异常、程序崩溃、健壮性内容详解: 再完美的代码也会遇到“意外”——比如数据库突然连不上、用户输入了非法内容、文件被删了…如果不管这些“意外”,程序会直接崩溃(像汽车撞墙一样)。

异常处理

就是给代码“装安全气囊”:遇到问题时不崩溃,而是“优雅地处理”(比如提示错误、重试操作),让程序更

健壮

(不容易挂掉)。 类比:你点外卖,万一商家没货(异常),APP不会闪退,而是提示“商品售罄”并推荐替代品——这就是“异常处理”的思路!

二、基础:try-except——捕获并处理异常

2. 异常处理入门:try-except——“试试看,出问题就处理” 🧪

关键字

:try语句、except子句、异常捕获 内容详解: Python用

try-except

捕获异常,格式是:把“可能出问题的代码”放在

try

里,“出问题后怎么处理”放在

except

里。比如处理“除以0”的错误:

def divide(a, b):
    try:
        # 可能出问题的代码:b为0会报错
        return a / b
    except ZeroDivisionError:
        # 捕获“除以0”异常,处理它
        print("错误:除数不能为0!")
        return None  # 返回一个安全的结果

# 测试:正常情况
print(divide(4, 2))  # 输出2.0
# 测试:异常情况
print(divide(4, 0))  # 输出“错误:除数不能为0!”和None

没有异常处理时,

4/0

会让程序崩溃;加了

try-except

,程序会提示错误并继续运行!

三、进阶:多异常捕获+捕获所有异常

3. 灵活处理:捕获多种异常+“兜底”处理 🎯

关键字

:多except子句、Exception基类、异常信息 内容详解: 一个

try

可以配多个

except

,捕获不同类型的异常;还能用

Exception

(所有异常的基类)“兜底”捕获未知异常:

def read_file(file_path):
    try:
        with open(file_path, "r") as f:
            return f.read()
    except FileNotFoundError:
        # 捕获“文件不存在”异常
        print(f"错误:文件{file_path}不存在!")
        return ""
    except PermissionError:
        # 捕获“权限不足”异常
        print(f"错误:没有读取{file_path}的权限!")
        return ""
    except Exception as e:
        # 兜底:捕获其他所有异常,e是异常对象(包含错误信息)
        print(f"未知错误:{e}")
        return ""

# 测试不同异常
read_file("不存在的文件.txt")  # 提示“文件不存在”
read_file("/root/敏感文件.txt")  # 提示“权限不足”
read_file(123)  # 提示“未知错误:expected str, bytes or os.PathLike object, not int”

这样不管遇到哪种错误,程序都能“温柔地”给出提示,而不是直接崩溃~

四、实战:Web应用的异常处理——数据库连接异常

4. Web场景:给数据库操作加“异常防护” 🕸️

关键字

:Flask异常处理、数据库异常、重试机制 内容详解: Web应用中,数据库连接失败是常见异常——用

try-except

给数据库操作加防护,甚至加“重试”功能:

from flask import Flask
import mysql.connector
import time

app = Flask(__name__)

def get_db_data(retry=3):
    while retry > 0:
        try:
            # 尝试连接数据库
            conn = mysql.connector.connect(
                host="localhost", user="root", password="你的密码", database="web_log_db"
            )
            cursor = conn.cursor()
            cursor.execute("SELECT COUNT(*) FROM access_log")
            result = cursor.fetchone()[0]
            conn.close()
            return result
        except mysql.connector.Error as e:
            # 捕获数据库异常
            print(f"数据库错误:{e},剩余重试次数{retry-1}")
            retry -= 1
            time.sleep(1)  # 等1秒再重试
    # 重试失败,返回默认值
    return "数据库连接失败"

@app.route("/log_count")
def log_count():
    count = get_db_data()
    return f"总访问次数:{count}"

if __name__ == "__main__":
    app.run(debug=True)

现在如果数据库临时断开,程序会重试3次;都失败了也会返回“数据库连接失败”,而不是让Web应用崩溃——用户体验会好很多!

五、高级:自定义异常+finally子句

5. 高阶技巧:自定义异常+finally“收尾” 🧩

关键字

:自定义异常、raise语句、finally子句 内容详解: 除了Python自带的异常,你还能

自定义异常

(处理业务相关的错误);

finally子句

则能保证“不管有没有异常,都执行收尾操作”:

# 自定义异常:业务相关的错误
class InvalidUserError(Exception):
    def __init__(self, user_id):
        self.user_id = user_id
        self.message = f"用户{user_id}不存在"
        super().__init__(self.message)

def get_user_info(user_id):
    # 模拟查询用户,不存在则抛自定义异常
    users = {"1": "张三", "2": "李四"}
    if user_id not in users:
        raise InvalidUserError(user_id)  # 主动抛异常
    return users[user_id]

def process_user(user_id):
    conn = None
    try:
        user = get_user_info(user_id)
        # 模拟数据库操作
        conn = mysql.connector.connect(...)
        print(f"处理用户{user}")
    except InvalidUserError as e:
        # 捕获自定义异常
        print(f"业务错误:{e.message}")
    except Exception as e:
        print(f"系统错误:{e}")
    finally:
        # 不管有没有异常,都关闭数据库连接
        if conn:
            conn.close()
            print("数据库连接已关闭")

# 测试:正常用户
process_user("1")  # 输出“处理用户张三”和“数据库连接已关闭”
# 测试:不存在的用户
process_user("3")  # 输出“业务错误:用户3不存在”和“数据库连接已关闭”

自定义异常让“业务错误”和“系统错误”分开处理;

finally

则保证资源(比如数据库连接)一定会被清理!

六、异常处理的原则:不要“吞掉”异常

6. 避坑指南:异常处理的“红线” 🚫

关键字

:异常吞没、日志记录、合理捕获 内容详解: 异常处理要避免一个常见错误:

吞没异常

(只写

except:

却不处理/记录错误)——比如:

# 错误示例:吞没异常,出问题了都不知道
try:
    4 / 0
except:
    pass  # 啥也不做

正确的做法是:

  • ✅ 只捕获“你能处理的异常”,未知异常交给上层处理;
  • ✅ 记录异常信息(比如用print或日志模块),方便排查问题;
  • ✅ 不要用异常处理“代替正常的条件判断”(比如用try判断用户输入是否为数字,不如直接用isdigit())。

记住:异常处理是“应对意外”,不是“掩盖错误”!