8.Python 异常 (Exception)

1. Python 中的错误

在 Python 开发过程中,可能会遇到 3 种错误:

  1. 语法错误 (Syntax Error) :代码不符合 Python 语法规则。

    • PyCharm 会给出红色的波浪线提示,运行会出现 SyntaxError
    python 复制代码
    # 计算 a 跟 b 的和
    a = 10
    b = 5
    print(a - b)  # 5 
  2. 逻辑错误 (Logic Error、Bug) :代码不符合业务逻辑。

    • PyCharm 不会给出任何提示信息。
  3. 异常 (Exception) :操作不合理、Python 无法正常处理你的代码。

    • Python 会抛出异常信息(比如 XxxError)。
    python 复制代码
    i = int('小码哥')
    print(i)
    
    print(10 / 0)

2. 异常的特点

  • 会直接导致程序终止运行
python 复制代码
print(1)
print(10 / 0)
print(2)

def test():
    print(2)
    print(10 / 0)
    print(3)

print(1)
test()
print(4)

# 运行结果:
# 1
# ZeroDivisionError: division by zero
# 1
# 2
# ZeroDivisionError: division by zero
  • 有时候来得猝不及防,把握不住
python 复制代码
age = int(input('请输入你的年龄:'))
print(age)

3. 异常的处理

在绝大部分情况下:

  • 我们都不希望程序因为异常而终止运行。
  • 我们更希望的是:
    • 能够"把握住"异常
    • 能够拦截(捕获)异常
    • 根据不同的异常信息作出不同的处理
    • 让程序保持正常运行

3.1 捕获异常的基本结构

tryexceptelsefinally 配合使用:

  • try :包含可能会产生异常的代码。
    • 一旦出现异常,会直接跳过 try 中剩余未执行的代码。
  • except :当出现异常时,会执行 except 中的代码。
    • 可以省略。
  • else :当没有出现异常时,会执行 else 中的代码。
    • 可以省略。只能在有 except 时使用
  • finally :不管是否出现异常,最终都会执行 finally 中的代码。
    • 可以省略。
python 复制代码
try:
    代码1
except:
    代码2
else:
    代码3
finally:
    代码4

综合示例:

python 复制代码
try:
    a = int(input('请输入第1个整数:'))
    print(1)
    b = int(input('请输入第2个整数:'))
    print(2)
    print(f'a除以b等于{a / b}')
    print(3)
except ValueError:
    print('输入的数据无法转成整数')
except ZeroDivisionError:
    print('0不能作为被除数')
else:
    print('很好,一切正常')
finally:
    print('操作处理完毕')
print(4)

3.2 常见的内置异常类型

  1. ZeroDivisionError :0 作为除数

    python 复制代码
    print(10 / 0) # ZeroDivisionError: division by zero
  2. IndexError :索引超出正常范围

    python 复制代码
    s = [11, 22, 33]
    print(s[5]) # IndexError: list index out of range
  3. NameError :无法找到名称(标识符)

    python 复制代码
    print(age) # NameError: name 'age' is not defined
  4. KeyError :无法找到字典的 key

    python 复制代码
    d = {'age': 18}
    print(d['name']) # KeyError: 'name'
  5. TypeError :使用了不恰当类型的对象

    python 复制代码
    print('age is ' + 18) # TypeError: can only concatenate str (not "int") to str
  6. ValueError :虽然类型正确,但值不正确

    python 复制代码
    n = int('娃哈哈') # ValueError: invalid literal for int() with base 10: '娃哈哈'
  7. AttributeError :操作(访问、赋值等)属性失败

    python 复制代码
    class Person:
        pass
        
    p = Person()
    print(p.age) # AttributeError: 'Person' object has no attribute 'age'

3.3 except 的高级用法

  • 省略异常类型except 后面可以不写异常类型,表示支持所有的异常类型。
python 复制代码
try:
    a = int(input('请输入第1个整数:'))
    b = int(input('请输入第2个整数:'))
    print(f'a除以b等于{a / b}')
    print([][10])
except ValueError:
    print('输入的数据无法转成整数')
except ZeroDivisionError:
    print('0不能作为被除数')
except:
    print('其他异常')
  • 捕获多个异常类型 :可以用元组同时表示多个异常类型。
python 复制代码
try:
    a = int(input('请输入第1个整数:'))
    b = int(input('请输入第2个整数:'))
    print(f'a除以b等于{a / b}')
except (ValueError, ZeroDivisionError):
    print('出现异常')
  • 接收异常对象 :可以用变量来接收异常对象(使用关键字 as)。
python 复制代码
try:
    n = int(input('请输入第1个整数:'))
    print(n)
except BaseException as e:
    print('出现异常', e)

try:
    a = int(input('请输入第1个整数:'))
    b = int(input('请输入第2个整数:'))
    print(f'a除以b等于{a / b}')
except (ValueError, ZeroDivisionError) as e:
    print('出现异常', e)

4. 异常的传播

  • 一旦函数/方法中的代码出现了异常:
    • 会直接跳过剩余的代码,函数/方法停止运行。
    • 函数/方法中产生的异常,会向外传播到当初调用函数/方法的地方。
  • 从异常的打印信息(Traceback),可以很清晰地看出异常的传播轨迹。
  • 异常会由内往外 传播出去,直到被拦截捕获或传播到全局作用域为止。
    • 可以想象成是在寻求帮助,看看哪位大神能够收了(处理)这个异常。
    • 当异常传播到全局作用域时,还没有被拦截捕获,就会导致程序终止运行,并将异常信息打印出来。

5. 抛出异常 (raise)

如果函数/方法的参数有问题,我们可以在函数/方法内部:

  1. 将不合理的值过滤掉。
  2. 抛出异常,告诉传递参数的人:你传递的参数有严重问题。

可以通过 raise 主动抛出异常:

  • raise 后面跟上的必须是异常类型(BaseException 类型或其子类类型)。
python 复制代码
class Person:
    def __init__(self):
        self.__age = 1
        
    @property
    def age(self):
        return self.__age
        
    @age.setter
    def age(self, age):
        if age < 1:  # 主动抛出异常
            raise ValueError('age不能小于1')
        if age > 120:  # 主动抛出异常
            raise ValueError('age不能大于120')
        self.__age = age

try:
    p = Person()
    p.age = -10
    print(p.age)
except ValueError as e:
    print('出现了异常', e.args[0])

6. 自定义异常

为了让异常的类型、描述信息更加精准,可以考虑自定义异常。

  • 一般建议 :自定义的异常类型,最终要继承自 Exception,而并不是 BaseException
python 复制代码
class AgeError(Exception):
    """自定义的异常类型,表示age有问题"""
    def __str__(self):
        return f'{self.args[0]}:{self.args[1]}值不合理'

class Person:
    def __init__(self):
        self.__age = 1
        
    @property
    def age(self):
        return self.__age
        
    @age.setter
    def age(self, age):
        if age < 1:  # 主动抛出异常
            raise AgeError('age不能小于1', age)
        if age > 120:  # 主动抛出异常
            raise AgeError('age不能大于120', age)
        self.__age = age

try:
    p = Person()
    p.age = 300
    print(p.age)
except AgeError as e:
    print('出现了异常', e)
相关推荐
装不满的克莱因瓶3 分钟前
了解 LangChain 中的 LLM 与 ChatModel 的差异
人工智能·python·ai·langchain·llm·agent·chatmodel
IT知识分享1 小时前
从零开发在线简繁转换工具:OpenCC 实战、避坑经验与方案选型
javascript·python
lunzi_08261 小时前
【学习笔记】《Python编程 从入门到实践》第8章:函数定义、参数传递与模块导入
笔记·python·学习
杨运交1 小时前
[030][Web模块]Spring Boot 验证与 OpenAPI 集成实战:从校验规则到文档生成
前端·spring boot·python
培培说证2 小时前
2026财务岗位如何快速提升自身能力
python
努力攻坚操作系统2 小时前
编程语言编译运行机制对比:C / Java / Python
java·c语言·python
godspeed_lucip2 小时前
LLM和Agent——专题6:Multi Agent 入门(5)
人工智能·python
Metaphor6923 小时前
使用 Python 给 PDF 设置背景色或背景图
数据库·python·pdf
郝亚军3 小时前
如何让pycharm-2026.1.2顶部菜单栏固定显示在最上端
python