错误处理是计算机科学中最重要的概念之一,它将通过处理导致程序退出的意外错误来帮助您提高代码的健壮性。
在本教程中,我们将学习如何在Python中处理异常。我们将涵盖以下主题:
- 错误与异常
- Python中的内置异常
- 没有处理异常的问题
- 处理异常
- 具有多个异常的除外子句
- 最后清理使用
- 自定义例外
可能有两种错误:
1.语法错误
2.异常(运行时遇到的错误)
语法错误
这是你在你的程序看,通常是因为在一个错误的最常见的错误空白,一个错误的语法,或者简单的拼写错误。如果您的程序在语法上不正确,例如下面给出的代码中的(,并且解析器将指向使用小箭头检测到错误的行,则会发生此类错误。
>>> if a > 5
File "
", line 1
if a > 5
^
SyntaxError: invalid syntax
例外:
即使语法正确,也可能导致错误,我们称之为错误异常,Python中有许多不同类型的异常,例如下面示例中的ValueError。
>>> a = "hello"
>>> int(a)
Traceback (most recent call last):
File "
", line 1, in
ValueError: invalid literal for int() with base 10: 'hello'
如果未正确处理异常,则可能导致程序意外停止。
Python中的内置异常
Python有许多有用的内置异常,您可能在编程时遇到这些异常。您将遇到的一些更常见的是:
AttributeError -在属性赋值或引用失败时引发。
ImportError -Raised未找到导入的模块。
IndexError - 当序列的索引超出范围时引发。
KeyError - 在字典中找不到键时引发。
KeyboardInterrupt - 当用户点击中断键(Ctrl + c或删除)时增加。
NameError - 在本地或全局范围内找不到变量时引发。
**SyntaxError **- 遇到语法错误时由解析器引发。
**IndentationError **- 在缩进不正确时引发。
ValueError - 当函数获取正确类型但值不正确的参数时引发。
ZeroDivisionError :当数字除以零时引发。
没有处理异常的问题
例外是暂停程序执行的条件,如果处理不当,可能会导致很多问题。考虑以下简单示例:
>>> def divide_my_number(num1, num2):
... result = num1 / num2
... print(f"num1/num2 gives {result}")
让我们用不同的值来调用这个函数。请注意,我们不会在此处理任何异常:
>>> divide_my_number(10,2)
num1/num2 gives 5.0
让我们将其除以零并仔细观察它会抛出的错误:
>>> divide_my_number(10,0)
Traceback (most recent call last):
File "
", line 1, in
File "
", line 2, in divide_my_number
ZeroDivisionError: division by zero
我们可以看到程序没有成功执行并返回了一个异常,可以正常处理以避免这种停顿。
零分割是一种常见的情况,我们可以有很多场景,我们不希望我们的程序意外停止,例如处理文件,API或任何我们不希望我们的用户使用的真实应用程序时看到这些奇怪的错误。
一旦我们将学习所有概念,我们将看到如何在函数(divide_my_number)中处理此异常。
python中的异常处理
异常处理提供了一种机制来处理代码的典型控制流中的错误或其他异常情况。
许多语言都有“Try-catch”块的概念。Python使用四个关键字:Try,Except,Else, Finally
可能引发异常的代码将进入
Try
块
如果引发异常,则
Except
块内的代码将运行
Else
是一个可选块,当程序中没有异常时会引发该块
最后
是一个可选块,它将在最后运行,无论是否引发异常。
让我们看一下下面的图片,以便更清晰
>>> try:
... num = int(input("Enter a number: "))
... except ValueError:
... print("Please Enter a Valid number")
...
Enter a number: passing string
Please Enter a Valid number
首先,执行try语句。如果没有异常,那么try语句将完成运行try块内的所有内容。如果try块中发生异常,则跳过行的其余部分,如果异常类型与except中提供的名称匹配,则将执行except子句(如上面代码中的ValueError)。如果异常与任何特定名称不匹配,则执行将停止。
捕获Python中的特定异常
一个except子句可能有多个异常,我们可以将它作为元组传递。
>>> try:
... num = int(input("Enter a number: "))
... except (ValueError, RuntimeError, TypeError, NameError):
... print("Please enter a valid number")
...
Enter a number: 6s
Please enter a valid number
除了也可以单独处理所有这些
>>> try:
... num = int(input("Enter a number: "))
... except ValueError:
... print("Please enter a valid number")
except NameError:
print("Please check your number once again")
Enter a number: 6s
Please enter a valid number
清理使用 finally
想象一下,您总是需要清理一些代码,例如关闭文件。最后是一个可选块,它将在最后运行,无论是否抛出异常。
>>> try:
... num = int(input("Enter a number: "))
... except ValueError:
... print("Please enter a valid number")
... else:
... print("I will run if no exception is thrown")
... finally:
... print("I will run no matter what will happen!!")
...
Enter a number: 9s
Please enter a valid number
I will run no matter what will happen!!
如您所见,即使发生异常,最终块也会被打印出来。
提高例外
该加薪语句允许程序员强制指定的异常发生。例如:
>>> def numbers_less_than_five(num):
... if num > 5:
... raise ValueError
... else:
... print(f"Number entered is {num}")
...
>>> numbers_less_than_five(4)
Number entered is 4
>>> numbers_less_than_five(8)
Traceback (most recent call last):
File "
", line 1, in
File "
", line 3, in numbers_less_than_five
ValueError
如果您想了解有关异常的更多信息,请查看官方文档8.错误和例外
自定义例外
Python有许多内置的Exception,但有时我们需要根据我们的用例定义自己的异常。
在Python中,我们可以通过继承Exception类来创建一个新类,如下例所示。
>>> class MyException(Exception):
... # Write your logic here
... pass
...
我们可以使用raise关键字提出自己的自定义异常
>>> raise MyException()
Traceback (most recent call last):
File "
", line 1, in
__main__.MyException
>>>
按照承诺,让我们使用我们学到的所有概念来处理函数 divide_my_number
>>> def divide_my_number(num1, num2):
... try:
... result = num1 / num2
... print(f"num1/num2 gives {result}")
... except TypeError:
... print("Number should be Integer")
... except ValueError:
... print("Please Enter a valid integer")
... except ZeroDivisionError:
... print("Divided by zero is not possible")
... else:
... print("Program got executed successfully, No exception raised")
让我们尝试所有边缘情况,看看我们的函数如何表现
>>> divide_my_number(10,5)
num1/num2 gives 2.0
Program got executed successfully, No exception raised
# When one of the parameters is a string
>>> divide_my_number(10,"s")
Number should be Integer
>>> divide_my_number(10,0)
Divided by zero is not possible
很少有最佳实践可以捕获特定的异常,这有助于您的程序在异常处理方面更加强大。
结论
我们了解了使用raise,try和except来处理异常的各种方法。我们还学到了各种各样的概念
- 在该try子句中,将执行所有语句,直到遇到异常。
- except 用于处理try块中引发的异常。
- else 只有在try子句中没有遇到异常时,块才会运行
- finally 使您能够执行应该始终运行的代码段,而不管是否引发异常。
- raise 允许您在程序的任何时候抛出异常。
- 我们可以创建自己的异常类,并根据自己的需要进行提升。
- 希望本文能帮助您理解Python中异常处理的概念。
请继续关注这样的更多教程。