Python中的错误处理 - 使用try、except、else和finally进行解释,并附带代码示例

最近,我的经理委派我创建一个自动报告。我设计的报告非常简单。它包括一些来自数据库的数字和一些基本的数学运算。我很兴奋最终可以向公司展示我的惊人的Python技能。

我完成并交付了产品。一切都很顺利。至少,直到大约两周后。我的报告由于除以零错误而随机失败了。来了个笑声轨道。

我的短篇故事缺少细节,但应该强调在编写程序时处理边界情况和错误的重要性。这份报告本应是展示我的Python技能的机会。然而,它却变成了一个有点尴尬的时刻。

所以,让我们花点时间学习使用Python标准库进行基本的错误处理。我将重点介绍一些你需要开始的东西。

在开始处理异常之前,你应该对Python基础知识有很好的掌握。你需要知道为什么会抛出异常才能处理它们!

(本文视频讲解:java567.com)

我们将介绍以下内容:

  1. Python中的Try和Except语句
  2. 使用Else子句进行条件执行
  3. 内置异常
  4. 自定义异常
  5. 性能考虑

Python中的Try和Except语句

tryexcept语句是处理异常的主要方法。它们的形式如下:

x = 0
try:
    print(5 / x)
except ZeroDivisionError:
    print("出错了")
    
# 出错了

让我们来分析上面的代码,以确保我们理解一致:

  1. 第1行将值0赋给变量x
  2. 第2行和第3行打开一个try子句,并尝试将5除以变量x
  3. 第4行和第5行打开一个except子句,用于任何ZeroDivisionError,并指示程序在尝试将任何东西除以0时打印一条消息

你可能已经注意到了问题。我的变量x的值是0,我试图将5除以x。世界上最好的数学家也不能除以0,Python也不能。那么会发生什么呢?

如果我们不处理错误,程序在尝试将5除以x时会立即终止。由于程序没有明确的指示如何处理异常,所以我们在第4行创建了except子句,并提供了程序在尝试将某些东西除以0时要采取的步骤。

这就是处理异常的整个思想:当程序遇到无法简单忽略的错误时,你需要告诉程序该怎么做。让我们看看tryexcept子句是如何工作的。

解析Try语句

TryExcept语句遵循一种模式,允许你可靠地处理代码中的问题。我们来看看这个模式。

首先,try子句中的代码尝试执行。

接下来,我们有三种可能性:

Try子句中没有错误

如果try子句中的代码没有任何错误,程序将:

  1. 执行try子句
  2. 跳过所有except子句
  3. 继续正常运行
x = 1
try:
    print(5 / x)
except ZeroDivisionError:
    print("出错了")

print("我在try子句之后执行!")

# 5.0
# 我在try子句之后执行!

你可以看到,在这个修改后的示例中,try子句(第3行和第4行)没有问题。代码将执行,except子句将被跳过,并且程序将在tryexcept语句结束后继续执行。

Try子句中有错误并且指定了异常

如果try子句中的代码确实引发异常并且在任何except关键字后指定了异常类型,程序将:

  1. 跳过try子句中剩余的代码
  2. 执行匹配的except子句中的任何代码
  3. 继续正常运行
x = 0
try:
    print(5 / x)
except:
    print("出错了")
    
print("我在try子句之后执行!")

# 出错了
# 我在try子句之后执行!

回到我的第一个例子,我将我们的变量x改回了值0,并尝试将5除以x。这会产生一个ZeroDivisionError。由于我的except语句指定了这种类型的异常,所以该子句中的代码在程序继续正常运行之前执行。

Try子句中有错误但未指定异常

最后,如果程序在try子句中引发了异常,但在任何except语句中未指定异常,那么程序将:

  1. 停止执行程序并抛出错误
x = 0
try:
    print(5 / y)
except:
    print("出错了")

print("我在try子句之后执行!")

# NameError: name 'y' is not defined

在上面的示例中,我试图将5除以变量y,但该变量不存在。这会引发一个NameError。我没有告诉程序如何处理NameError,所以唯一的选择就是终止程序。

清理工作

Tryexcept是处理错误的主要工具,但你可以使用的一个可选子句是finallyfinally子句将始终执行,无论是否发生错误。

x = 0
try:
    print(5 / x)
except ZeroDivisionError:
    print("我是except子句!")
finally:
    print("我是finally子句!")

print("我在try子句之后执行!")

# 我是except子句!
# 我是finally子句!
# 我在try子句之后执行!

在这个例子中,我创建了我们喜欢的ZeroDivisionError。你可以看到执行顺序是:

  1. except子句
  2. finally子句
  3. 之后的任何代码

一旦我们修复try子句不再引发错误,你仍然会看到类似的执行顺序。except子句不再运行,try子句将执行。

x = 1
try:
    print(5 / x)
except ZeroDivisionError:
    print("我是except子句!")
finally:
    print("我是finally子句!")

print("我在try子句之后执行!")

# 5.0
# 我是finally子句!
# 我在try子句之后执行!

你会注意到唯一的区别是try子句成功执行,因为没有抛出异常。finally子句和之后的代码会像你预期的那样执行。

这对于一些情况很有用,当你想要无论tryexcept子句的结果如何都要进行清理时。关闭连接、关闭文件和记录日志等操作都是finally子句的很好候选对象。

使用Else子句进行条件执行

另一个可选子句是else子句。else子句很简单:如果try子句中的代码执行时没有抛出错误,那么else子句中的代码也将执行。

x = 1
try:
    print(5 / x)
except ZeroDivisionError:
    print("我是except子句!")
else:
    print("我是else子句!")
finally:
    print("我是finally子句!")

print("我在try子句之后执行!")

# 5.0
# 我是else子句!
# 我是finally子句!
# 我在try子句之后执行!

这个例子的执行顺序是:

  1. try子句
  2. else子句
  3. finally子句
  4. 之后的任何代码

如果在try子句中出现异常或错误,else子句将被忽略。

x = 0
try:
    print(5 / x)
except ZeroDivisionError:
    print("我是except子句!")
else:
    print("我是else子句!")
finally:
    print("我是finally子句!")

print("我在try子句之后执行!")

# 我是except子句!
# 我是finally子句!
# 我在try子句之后执行!

内置异常

到目前为止,你已经看到我写了两种不同的命名异常:NameErrorZeroDivisionError。如果我需要其他异常呢?

Python标准库中有一整套异常列表。这些异常几乎可以满足你处理任何错误或异常的需求。

以下是一些可能很重要的异常:

  • KeyError – 在字典中找不到键
  • IndexError – 在可迭代对象上索引超出范围
  • TypeError – 将函数或操作用于错误类型的对象
  • OSError – 一般的操作系统错误

还有很多其他的异常,可以在Python文档中找到。我鼓励你去看看。你不仅会更擅长处理错误,还会探索你的Python程序可能真正出错的地方。

自定义异常

如果你需要扩展功能,还可以定义自定义异常。

class FooError(Exception):
    def __init__(self, message):
        self.message = message
    
    def foo(self):
        print("bar")

在上面的示例中,我创建了一个新类,并将其扩展自异常类。现在,我可以编写自定义功能,并像对待其他对象一样处理此异常。

try:
    raise FooError("这是一个测试错误")
except FooError as e:
    e.foo()

# bar

这里,我故意引发了我的新FooError。我捕获了FooError,并给它起了别名e。现在,我可以访问我在创建的类中内置的foo()方法。

这为处理错误提供了一系列可能性。自定义日志记录、更深入的跟踪或任何你需要的其他功能都可以编码和创建。

性能考虑

现在你已经了解了tryexcept和异常对象的基础知识,你可以开始考虑在你的代码中使用它们来优雅地处理错误。但是,代码性能会受到多大影响呢?

简短的答案是没有。随着Python 3.11的发布,当没有抛出异常时,使用tryexcept语句几乎不会减慢速度。

捕获错误确实会导致一些减速。但总的来说,捕获这些错误总比整个程序崩溃好。

在Python的早期版本中,使用tryexcept子句确实会导致一些额外的执行时间。如果你不是最新的,请记住这一点。

总结

感谢你阅读到这里。你的未来自己和客户会为你的错误处理感谢你。

我们讨论了tryexceptelsefinally子句及其执行顺序,以及在什么情况下它们被执行。我们还复习了创建自定义异常的基础知识。

最重要的是要记住,tryexcept子句是捕获错误的主要方式,你应该在有风险、容易出错的代码中使用它们。

此外,请记住,捕获错误将使你的代码更加弹性,并让你看起来更像一个优秀的程序员。

(本文视频讲解:java567.com)

Error Handling in Python – try, except, else, & finally Explained with Code Examples

  • 38
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Pythontry-except-else-finally是一种异常处理机制,用于处理可能会导致程序崩溃的代码块。它们的作用如下: - try:尝试执行一段可能会引发异常的代码。 - except:在try发生异常时执行的代码块。 - else:在try没有发生异常时执行的代码块。 - finally:无论try是否发生异常,都会执行的代码块。 下面是一个简单的例子,演示了这些关键字的使用方法: ```python try: # 尝试执行代码块 f = open("file.txt", "r") except FileNotFoundError: # 文件不存在,执行这里的代码块 print("File not found") else: # 如果try块没有发生异常,执行这里的代码块 print(f.read()) f.close() finally: # 无论try是否发生异常,都会执行这里的代码块 print("Execution complete") ``` 在这个例子,程序尝试打开一个文件,如果文件不存在,则会引发FileNotFoundError异常。如果try块成功执行,它将读取文件并关闭文件。无论发生什么,最后都会执行“Execution complete”的语句。 希望这可以帮助你理解try-except-else-finally关键字在Python使用方式。 ### 回答2: Pythontryexcept、else、finally是一种异常处理机制,用于处理程序在运行过程出现的异常。以下是对这四个关键字的详细解释: 1. try:用于包含可能发生异常的代码块,并且必须与except、else和finally关键字一起使用。 2. except:用于捕获try代码的异常,如果try代码没有异常,则不会执行except代码块。 3. else:用于在try代码没有异常时执行的代码块,通过执行else代码块,我们可以保证在没有异常时执行特定的代码,否则我们需要让异常处理代码块执行。 4. finally:用于包含必须在tryexcept代码块完成后必须执行的代码。即使tryexcept代码发生了异常,finally代码块也会执行。 以下是Python处理异常的具体流程: 程序首先执行try代码的语句,如果没有异常,则执行else代码的语句,最后执行finally代码的语句。如果try代码出现异常,程序将跳到与异常匹配的except代码,执行相应的异常处理语句,最后执行finally代码的语句。 在Python,我们可以有多个except代码块,每个except都会捕获不同类型的异常。我们也可以使用Exception关键字捕获所有的异常类型。另外,还可以使用raise关键字在代码手动触发异常,并使用assert关键字来检测特定条件是否为真,如果不是,则触发异常。 总之,利用tryexcept、else、finally这四个关键字,Python可以方便而有效地处理程序运行时可能出现的各种异常情况。 ### 回答3: Pythontry except else finally结构是一种异常处理机制,它允许我们在程序运行时捕获并处理错误,从而使程序更加健壮、容错能力更强。try except else finally结构可以分为以下几个部分: 1. try块:try块是我们尝试执行的代码块,其包含我们可能想要捕获异常的代码。 2. except块:except块是我们处理异常的代码块,它指定了我们想要捕获的异常类型。当try出现异常时,程序会跳转到except块,并执行其代码。 3. else块:else块是在try块未发生异常时执行的代码块。如果try代码成功执行,那么程序会自动跳到else块,并执行其代码。 4. finally块:finally块是在try块和except块均执行完毕后执行的代码块。无论是否出现异常,程序都会执行finally代码。 下面是一个例子: ```python try: x = int(input("请输入一个数字:")) except ValueError: print("输入错误,您需要输入一个数字") else: print("您输入的数字为:", x) finally: print("程序执行完毕") ``` 该程序会提示用户输入一个数字,如果用户输入的不是数字,则会触发ValueError异常,程序会跳转到except块,并输出一条错误消息。如果用户输入的是数字,则会跳转到else块,并输出用户输入的数字。无论何时,程序都会执行finally代码,并显示“程序执行完毕”。 总之,Pythontry except else finally结构是一种非常有用的异常处理机制,可以帮助我们避免程序运行时出现的错误,提高程序的健壮性和容错能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值