Python 异常处理!

简介: 本文详细介绍了Python中的异常处理,包括try、except和finally语句的使用方法。文章区分了语法错误与异常,并列举了Python中常见的异常类型,如`SyntaxError`、`TypeError`等。通过具体示例展示了如何使用try-except块捕获和处理异常,以及如何结合else和finally子句增强代码的健壮性和可读性。此外,还介绍了如何使用raise语句主动抛出异常。通过合理的异常处理,可以提高程序的可靠性与调试效率,但也可能带来性能开销和代码复杂度的增加。

嗨,你好啊,我是猿java

这篇文章,我们将通过适当的示例讨论如何使用try、except和finally语句来处理Python中的异常。

Python中的错误可以分为两种类型,即语法错误和异常。错误是由于程序中的问题而导致程序停止执行的情况。而异常是在出现某些内部事件时引发的,从而改变程序的正常流程。

Python中的异常类型

在 Python中,有几种内置的异常,当程序执行过程中出现错误时会抛出这些异常,以下是 Python中最常见的一些异常类型:

  • SyntaxError: 当解释器在代码中遇到语法错误时引发此异常,例如拼写错误的关键字、缺少的冒号或不平衡的括号。
  • TypeError: 当一个操作或函数应用于错误类型的对象时引发此异常,例如将字符串加到整数上。
  • NameError: 当变量或函数名称在当前作用域中未找到时引发此异常。
  • IndexError: 当列表、元组或其他序列类型的索引超出范围时引发此异常。
  • KeyError: 当在字典中找不到键时引发此异常。
  • ValueError: 当函数或方法调用时提供了无效的参数或输入时引发此异常,例如尝试将字符串转换为整数而该字符串不表示有效整数。
  • AttributeError: 当对象上找不到属性或方法时引发此异常,例如试图访问类实例的不存在的属性。
  • IOError: 当输入/输出操作失败时引发此异常,例如读取或写入文件时发生输入/输出错误。
  • ZeroDivisionError: 当尝试将数字除以零时引发此异常。
  • ImportError: 当导入语句未能找到或加载模块时引发此异常。

这些只是许多可能在Python中发生的异常类型中的一部分。通过使用try-except块或其他错误处理技术,适当地处理异常是很重要的,这样可以优雅地处理错误并防止程序崩溃。

语法错误和异常的区别

语法错误: 顾名思义,这种错误是由代码中的语法错误引起的,它会导致程序的终止。

以下示例代码中存在语法错误。‘if'语句应紧跟一个冒号(:),并且‘print'语句应缩进到‘if'块内部。

amount = 10000
if(amount > 2999)
print("amount > 2999")

异常: 异常是在程序语法正确的情况下引发的错误,但代码结果却发生错误。此错误不会停止程序的执行,但会改变程序的正常流程。

如下示例代码中,我们将‘marks’除以零,因此会发生称为‘ZeroDivisionError’的错误。‘ZeroDivisionError’ 发生在尝试将任何数字除以0时。

marks = 10000
a = marks / 0
print(a)

在上述示例中,由于我们试图将一个数字除以0,因此引发了ZeroDivisionError异常。

注意: Exception是Python中所有异常的基类。

1) TypeError: 当一个操作或函数应用于错误类型的对象时引发此异常。

以下示例试图将两种不同数据类型相加,引发了‘TypeError’异常:

x = 5
y = "hello"
z = x + y

输出:

Traceback (most recent call last):
  File "7edfa469-9a3c-4e4d-98f3-5544e60bff4e.py", line 4, in <module>
    z = x + y
TypeError: unsupported operand type(s) for +: 'int' and 'str'

使用try-except块解决它:

代码尝试将一个整数(‘x’)和一个字符串(‘y’)相加,这是无效的操作,并会引发‘TypeError’异常。代码使用‘try’和‘except’块捕获此异常并打印错误消息。

x = 5
y = "hello"
try:
    z = x + y
except TypeError:
    print("错误: 不能将int和str相加")

输出:

错误: 不能将int和str相加

Try和Except语句——捕获异常

Try和except语句用于捕获和处理Python中的异常。可能引发异常的语句被放在try块中,而处理异常的语句则写在except块中。

示例:这里我们试图访问数组中越界的元素并处理对应的异常。

a = [1, 2, 3]
try: 
    print ("第二个元素 = %d" %(a[1]))
    print ("第四个元素 = %d" %(a[3]))

except:
    print ("发生错误")

输出:

第二个元素 = 2
发生错误

在上述示例中,可能导致错误的语句放在try语句中(我们的案例中是第二个print语句)。第二个打印语句尝试访问列表中的第四个元素,而该元素不存在,因而抛出异常。该异常被except语句捕获。

捕获特定异常

try语句可以有多个except条款,以指定不同异常的处理程序。请注意,最多只有一个处理程序会被执行。例如,我们可以在上述代码中添加IndexError。添加特定异常的一般语法是:

try:
    # 语句
except IndexError:
    # 语句
except ValueError:
    # 语句

示例:捕获Python中的特定异常

代码定义了一个名为‘fun(a)’的函数,该函数根据输入a计算b。如果a小于4,它会尝试除以零,从而导致‘ZeroDivisionError’。代码在try-except块中调用fun(3)和fun(5)。它处理fun(3)时的ZeroDivisionError,并打印“ZeroDivisionError发生并已处理”。由于代码中没有‘NameError’异常,因此‘NameError’块不被执行。

def fun(a):
    if a < 4:
        b = a/(a-3)
    print("b的值 = ", b)

try:
    fun(3)
    fun(5)
except ZeroDivisionError:
    print("ZeroDivisionError发生并已处理")
except NameError:
    print("NameError发生并已处理")

输出:

ZeroDivisionError发生并已处理

如果注释掉fun(3)行,输出将是:

NameError发生并已处理

上述输出是因为一旦 Python尝试访问 b的值,就会发生NameError异常。

带有 Else子句的Try语句

在Python中,你还可以在try-except块中使用else子句,该子句必须位于所有except块之后。代码仅在try块不抛出异常时才进入else块。

带有Else子句的Try语句

代码定义了一个名为AbyB(a, b)的函数,该函数计算c为((a+b) / (a-b))并处理潜在的ZeroDivisionError。如果没有发生除以零错误,它会打印结果。调用AbyB(2.0, 3.0)计算并打印-5.0,而调用AbyB(3.0, 3.0)尝试除以零,结果导致ZeroDivisionError,该异常被捕获并打印“a/b结果为0”。

def AbyB(a , b):
    try:
        c = ((a+b) / (a-b))
    except ZeroDivisionError:
        print ("a/b结果为0")
    else:
        print (c)

AbyB(2.0, 3.0)
AbyB(3.0, 3.0)

输出:

-5.0
a/b结果为0

Finally关键字在Python中的用法

Python提供了finally关键字,它始终在try和except块之后执行。无论是try块正常终止还是try块由于某些异常终止,最终块总是执行。最终块中的代码总是被执行。

语法:

try:
    # 一些代码
except:
    # 可选块
    # 处理异常(如果需要)
else:
    # 如果没有异常则执行
finally:
    # 一些总是执行的代码

以下示例代码尝试执行除以零的整数除法,导致ZeroDivisionError。它捕获该异常并打印“不能除以零”。无论是否发生异常,最终块会执行并打印“这总是执行”。

try:
    k = 5//0 
    print(k)
except ZeroDivisionError:
    print("不能除以零")
finally:
    print('这里总是执行')

输出:

不能除以零
这里总是执行

抛出异常

raise语句允许程序员强制发生特定异常。raise的唯一参数说明要引发的异常。这个参数必须是异常实例或异常类(从Exception派生的类)。

这段代码在try块中使用raise语句,带有消息“Hi there”主动引发一个NameError异常。然后,它捕获NameError异常,打印“发生异常”,并使用raise重新抛出相同的异常。这展示了如何在Python中引发和处理异常,允许自定义的错误消息和进一步的异常传播。

try: 
    raise NameError("Hi there")
except NameError:
    print ("发生异常")
    raise

上述代码的输出将只会打印一行“发生异常”,但由于最后一行中的raise语句,最后也会发生运行时错误。所以在你的命令行上,输出将是:

Traceback (most recent call last):
  File "/home/d6ec14ca595b97bff8d8034bbf212a9f.py", line 5, in <module>
    raise NameError("Hi there")  # Raise Error
NameError: Hi there

异常处理的优点:

  • 提高程序的可靠性: 通过正确处理异常,可以防止程序因意外错误或输入而崩溃或产生错误结果。
  • 简化错误处理: 异常处理允许将错误处理代码与主程序逻辑分离,使程序更易读和维护。
  • 代码更简洁: 使用异常处理,可以避免使用复杂的条件语句来检查错误,从而使代码更简洁、更易读。
  • 调试更容易: 当引发异常时,Python解释器会打印出异常发生的确切位置的追踪信息,使得调试代码更加容易。

异常处理的缺点:

  • 性能开销: 异常处理可能比使用条件语句检查错误要慢,因为解释器需要执行额外的工作来捕获和处理异常。
  • 增加代码复杂性: 异常处理可能使你的代码更复杂,特别是当你需要处理多种类型的异常或实现复杂的错误处理逻辑时。
  • 可能的安全风险: 处理不当的异常可能会暴露敏感信息或在代码中创建安全漏洞,因此务必要仔细处理异常,避免暴露过多有关程序的信息。

学习交流

如果你觉得文章有帮助,请帮忙转发给更多的好友,或关注:猿java,持续输出硬核文章。

目录
相关文章
|
23天前
|
弹性计算 人工智能 架构师
阿里云携手Altair共拓云上工业仿真新机遇
2024年9月12日,「2024 Altair 技术大会杭州站」成功召开,阿里云弹性计算产品运营与生态负责人何川,与Altair中国技术总监赵阳在会上联合发布了最新的“云上CAE一体机”。
阿里云携手Altair共拓云上工业仿真新机遇
|
15天前
|
存储 关系型数据库 分布式数据库
GraphRAG:基于PolarDB+通义千问+LangChain的知识图谱+大模型最佳实践
本文介绍了如何使用PolarDB、通义千问和LangChain搭建GraphRAG系统,结合知识图谱和向量检索提升问答质量。通过实例展示了单独使用向量检索和图检索的局限性,并通过图+向量联合搜索增强了问答准确性。PolarDB支持AGE图引擎和pgvector插件,实现图数据和向量数据的统一存储与检索,提升了RAG系统的性能和效果。
|
20天前
|
机器学习/深度学习 算法 大数据
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
2024“华为杯”数学建模竞赛,对ABCDEF每个题进行详细的分析,涵盖风电场功率优化、WLAN网络吞吐量、磁性元件损耗建模、地理环境问题、高速公路应急车道启用和X射线脉冲星建模等多领域问题,解析了问题类型、专业和技能的需要。
2572 22
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
|
18天前
|
人工智能 IDE 程序员
期盼已久!通义灵码 AI 程序员开启邀测,全流程开发仅用几分钟
在云栖大会上,阿里云云原生应用平台负责人丁宇宣布,「通义灵码」完成全面升级,并正式发布 AI 程序员。
|
3天前
|
JSON 自然语言处理 数据管理
阿里云百炼产品月刊【2024年9月】
阿里云百炼产品月刊【2024年9月】,涵盖本月产品和功能发布、活动,应用实践等内容,帮助您快速了解阿里云百炼产品的最新动态。
阿里云百炼产品月刊【2024年9月】
|
2天前
|
存储 人工智能 搜索推荐
数据治理,是时候打破刻板印象了
瓴羊智能数据建设与治理产品Datapin全面升级,可演进扩展的数据架构体系为企业数据治理预留发展空间,推出敏捷版用以解决企业数据量不大但需构建数据的场景问题,基于大模型打造的DataAgent更是为企业用好数据资产提供了便利。
159 2
|
19天前
|
机器学习/深度学习 算法 数据可视化
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
2024年中国研究生数学建模竞赛C题聚焦磁性元件磁芯损耗建模。题目背景介绍了电能变换技术的发展与应用,强调磁性元件在功率变换器中的重要性。磁芯损耗受多种因素影响,现有模型难以精确预测。题目要求通过数据分析建立高精度磁芯损耗模型。具体任务包括励磁波形分类、修正斯坦麦茨方程、分析影响因素、构建预测模型及优化设计条件。涉及数据预处理、特征提取、机器学习及优化算法等技术。适合电气、材料、计算机等多个专业学生参与。
1570 16
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
|
21天前
|
编解码 JSON 自然语言处理
通义千问重磅开源Qwen2.5,性能超越Llama
击败Meta,阿里Qwen2.5再登全球开源大模型王座
942 14
|
3天前
|
Linux 虚拟化 开发者
一键将CentOs的yum源更换为国内阿里yum源
一键将CentOs的yum源更换为国内阿里yum源
185 2
|
16天前
|
人工智能 开发框架 Java
重磅发布!AI 驱动的 Java 开发框架:Spring AI Alibaba
随着生成式 AI 的快速发展,基于 AI 开发框架构建 AI 应用的诉求迅速增长,涌现出了包括 LangChain、LlamaIndex 等开发框架,但大部分框架只提供了 Python 语言的实现。但这些开发框架对于国内习惯了 Spring 开发范式的 Java 开发者而言,并非十分友好和丝滑。因此,我们基于 Spring AI 发布并快速演进 Spring AI Alibaba,通过提供一种方便的 API 抽象,帮助 Java 开发者简化 AI 应用的开发。同时,提供了完整的开源配套,包括可观测、网关、消息队列、配置中心等。
711 12