"try 和"else "语句用于流程控制。
异常,也被称为运行时错误,是一个在Python程序执行过程中发生的事件。当该错误发生时,它会中断Python程序,并通过向控制台打印一个*"回溯 "*来产生错误信息,其中包含关于该异常的信息以及它是如何被引发的。
为了防止程序中断,*"捕捉 "异常是很重要的。这里的"捕捉 "*指的是一旦异常发生后执行的一个代码块。*except "*语句中包含了上述代码块。
换句话说,*"try "*语句的存在是为了通过向程序传递一系列指令来对异常进行流程控制,以处理引发的错误。
异常可以通过多种方式产生,例如向函数传递无效参数、执行某些非法操作或故意/明确地提出。
另一方面,*"else "*语句包含了在没有错误的情况下要执行的其余程序代码。
异常类型
| 异常 | 错误的原因 |
|---|---|
| 断言错误(AssertionError | 当一个断言语句失败时引发的。 |
| 属性错误(AttributeError | 当属性赋值或引用失败时引发。 |
| EOFError | 当input()函数遇到文件结束条件时引发。 |
| 浮点错误(FloatingPointError | 当浮点操作失败时引发。 |
| 生成器退出 | 当发电机的close()方法被调用时引发。 |
| 导入错误 | 当导入的模块没有找到时引发。 |
| 索引错误 | 当一个序列的索引超出范围时引发。 |
| 密钥错误(KeyError | 当在字典中找不到一个键时引发。 |
| 键盘中断 | 当用户点击中断键(Ctrl+C或Delete)时引发。 |
| 内存错误 | 当一个操作耗尽内存时引发。 |
| 名称错误 | 当一个变量在本地或全局范围内没有找到时引发。 |
| 未实现的错误(NotImplementedError | 由抽象方法引发。 |
| OSError | 当系统操作导致系统相关错误时引发。 |
| 溢出错误(OverflowError | 当一个算术运算的结果太大,无法表示时引发。 |
| 引用错误 | 当使用弱引用代理访问一个垃圾收集的引用时,引发该错误。 |
| 运行时错误(RuntimeError | 当一个错误不属于任何其他类别时引发。 |
| 停止迭代 | 由next()函数引发,表示迭代器没有进一步的项目可供返回。 |
| 语法错误(SyntaxError | 遇到语法错误时由解析器引发。 |
| 缩进错误 | 缩进不正确时引发。 |
| TabError | 当缩进由不一致的制表符和空格组成时引发。 |
| 系统错误 | 解释器检测到内部错误时引发。 |
| 系统退出 | 由sys.exit()函数引发。 |
| 类型错误 | 当一个函数或操作被应用于一个不正确的类型的对象时引发。 |
| 未绑定的本地错误(UnboundLocalError | 当在一个函数或方法中对一个局部变量进行引用,但没有为该变量绑定值时引发。 |
| UnicodeError | 当发生与Unicode相关的编码或解码错误时引发。 |
| UnicodeEncodeError | 在编码过程中发生与Unicode相关的错误时引发。 |
| UnicodeDecodeError | 当在解码过程中发生与Unicode相关的错误时引发。 |
| UnicodeTranslateError | 在翻译过程中发生与Unicode相关的错误时引发。 |
| ValueError | 当一个函数得到一个类型正确但价值不正确的参数时引发。 |
| 零除错误 | 当除法或模数操作的第二个操作数为零时引发。 |
错误处理示例
- 断言错误(AssertionError)
在编程中,"断言 "语句用于声明编码时的一个特定条件为真。在执行程序时,如果条件为真,则执行下一行代码。然而,如果条件是假的,程序就会停止运行并返回一个AssertionError异常。
像其他异常一样,这个异常可以由用户手动处理,打印出用户定义的自定义错误信息,也可以用默认的异常处理程序来处理。下面的例子更好地说明了这一点。
例1 (手动处理断言错误异常)
代码:
#Handling it manually
try:
x = 1
y = 0
assert y != 0, "Invalid Operation"
print(x / y)
#the errror_message provided by the user gets printed
except AssertionError as msg:
print(msg)
输出
Invalid Operation
例2 (默认的断言错误异常处理)
代码:
#Roots of a quadratic equation
import math
def quad(a, b, c):
try:
assert a != 0, "Not a quadratic equation as coefficient of x ^ 2 can't be 0"
D = (b * b - 4 * a*c)
assert D>= 0, "Roots are imaginary"
r1 = (-b + math.sqrt(D))/(2 * a)
r2 = (-b - math.sqrt(D))/(2 * a)
print("Roots of the quadratic equation are :", r1, "", r2)
except AssertionError as msg:
print(msg)
quad(-1, 5, -6)
quad(1, 1, 6)
quad(2, 12, 18)
输出:
Roots of the quadratic equation are : 2.0 3.0
Roots are imaginary
Roots of the quadratic equation are : -3.0 -3.0
- AttributeError:
当一个属性引用或赋值失败时,就会发生AttributeError。换句话说,当用户试图做一个无效的属性引用时,可以为用户定义的类引发AttributeError。
例如,如果在处理整数时,我们要使用与字符串相关的方法,程序会引发AttributeError,因为整数不支持与字符串相关的方法。
由于Python是区分大小写的,方法或变量的拼写变化将引发AttributeError。
例子 1 (默认的 AttributeError 异常处理)
代码
#Handling it manually
try:
x = 1
y = 0
assert y != 0, "Invalid Operation"
print(x / y)
except AssertionError as msg:
print(msg)
输出
Invalid Operation
- EOFError:
EOF (简称为 文件结束)错误发生在Python中,当解释器在执行所有的代码之前就已经到达了程序的终点。它通常是由于没有为循环声明语句,或者在编写代码块时没有关闭小括号或大括号而产生的。
例子 1 (默认的 EOFError 异常处理)
代码:
try:
n = int(input())
print(n * 10)
except EOFError as e:
print(e)
输出:
EOF when reading a line
- FloatingPointError:
虽然被错误地认为是一个 "错误",但是当浮点数的内部表示法(使用固定的二进制数(通常是53位)来表示一个十进制数)无法用超过这个限制的二进制数来表示十进制数时,就会发生FloatingPoint错误;从而导致小的舍入错误。
这是一个常见的编程问题,在处理需要精确精度的数学问题时出现。在条件语句中使用这些数字时也会出现这种情况。
例子1 (手动浮点错误异常处理)
代码:
try:
a = 10
b = 3
c = a / b
print(c)
except FloatingPointError:
print("Floating point error has occurred")
输出:
Floating point error has occurred
- ImportError:
当一个模块或一个模块的成员不能被导入或不存在时,就会产生ImportError。
Example 1 (Manual ImportError Exception Handling)
代码:
try:
import nibabel
except ImportError:
print(“Such module does not exist!”)
输出:
Such module does not exist!
- IndexError:
在处理任何*"可索引 "的对象时都可能发生IndexError*(如 字符串, 图元,以及 列表),当试图从这样的对象中访问一个不存在于该对象中的元素时,就会发生索引错误。
例如,如果我们有一个10个元素的列表,索引在0到9的范围内。因此,试图访问一个索引为10或更大的元素将导致程序引发一个IndexError,信息为*"IndexError: list index out of range"。*
比如说。
例子1 (手动处理IndexError 异常)
代码
try:
a = [‘a’, ‘b’, ‘c’]
print(a[4])
except IndexError:
print(“Index out of range!”)
else:
print(“Success! No error raised!”)
输出
Index out of range!
- KeyError
在 Python 中,当试图访问一个不在字典中的键时,会产生一个KeyError异常。
例子 1 (手动处理 KeyError 异常)
代码
try:
a = [1:‘a’, 2:‘b’, 3:‘c’]
print(a[4])
except KeyError:
print(“Key Error raised!”)
else:
print(“Success! No error raised!”)
输出
Key Error raised!
- KeyboardInterrupt:
当用户/程序员意外或故意按下*"Ctrl + C "或"Del "键而中断程序的正常执行时,就会产生一个键盘中断*。
例子1 (手动键盘中断异常处理)
代码
try:
inp = input()
print(‘Press Ctrl + C or Interrupt the Kernel:’)
except KeyboardInterrupt:
print(‘Caught KeyboardInterrupt’)
else:
print(‘No exception occurred’)
输出
Caught KeyboardInterrupt
- NameError
使用一个未定义的变量、函数或模块发生NameError。
例1 (手动处理NameError异常)
代码:
#The try block will generate a NameError, because x is not defined:
try:
print(x)
except NameError:
print("Variable x is not defined")
else:
print("Something else went wrong")
输出
Variable x is not defined
- OSError:
在使用操作系统模块时,当操作系统(Operating System)特定的系统函数返回一个与系统有关的错误时,就会产生一个OSError,包括**I/O(输入/输出)故障,如"找不到文件 "或"磁盘满"。
例子1 (手动OSError异常处理)
代码
# importing os module
import os
r, w = os.pipe()
try :
print(os.ttyname(r))
except OSError as error :
print("File descriptor is not associated with any terminal device")
输出
File descriptor is not associated with any terminal device
- OverflowError
Python中的OverflowError表示一个算术操作已经超过了Python运行时在该特定实例中的限制。
例子 1 (手动处理溢出错误异常)
代码
try:
import math
print(math.exp(1000))
except OverflowError:
print(“OverFlow Exception Raised.”)
else:
print(“Success, no error!”)
输出
OverFlow Exception Raised.
- RuntimeError
RuntimeError是在程序成功编译后引发的。如果程序在运行时出了问题,它就会由运行时系统产生。大多数运行时错误信息包括错误发生的位置和正在执行的函数等信息。
运行时错误通常是在软件发布前的调试过程中发现的。在程序已经向公众发布的情况下,开发者通常会发布补丁,或旨在修复错误的小型更新。
以下是各种常见的运行时错误。 逻辑错误, 输入/输出错误, 未定义对象错误, 除以零的错误,等等。
例子1 (手动运行时错误异常处理)
代码
# Python program to handle simple runtime error
#Python 3
a = [1, 2, 3]
try:
print ("Second element = %d" %(a[1]))
# Throws error since there are only 3 elements in array
print ("Fourth element = %d" %(a[3]))
except:
print ("An error occurred")
输出
Second element = 2
An error occurred
- 语法错误(SyntaxError)。
语法错误是由于在使用Python时遇到的错误而引发的,通常是由于错误的拼写造成的。语法错误也可以由于省略关键词、省略符号以及出现空的代码块而引发。
例子1 (手动语法错误异常处理)
代码
try:
a = 8
b = 10
c = ab
except SytaxError:
print(“Wrong syntax!”)
输出
Wrong syntax!
- IndentationError:
IndentationError发生在空格或制表符没有正确放置的情况下。它通常是由于在处理语句、用户定义的函数或类时观察到的不良缩进做法而引起的。
例子1 (手动处理缩进错误的异常)
代码
try:
if(a<3):
print("gfg")
except IndentationError:
print(“An indentation was expected!”
输出
An indentation was expected!
- TabError:
TabError是由于在同一个代码块中缩进时不一致地使用制表符和空格而引起的。
例1 (手动处理TabError异常)
代码
numbers = [3.50, 4.90, 6.60, 3.40]
def calculate_total(purchases):
try:
total = sum(numbers)
return total
except TabError:
print(“Inconsistent use of tab spaces”)
total_numbers = calculate_total(numbers)
print(total_numbers)
输出
Inconsistent use of tab spaces
- TypeError:
当对一个不正确/不支持的对象类型进行操作时,会引发TypeError。换句话说,它是在操作中使用不适当的数据类型对象时引发的异常。例如,将一个字符串和一个整数值相加将引发一个TypeError,因为它们不兼容。
例子1 (手动处理TypeError 异常)
代码
try:
geek = "Geeks"
num = 4
print(geek + num + geek)
except TypeError:
print(“Must be strings”)
输出
Must be strings
- UnicodeEncodeError
UnicodeEncodeError是在对unicode字符串进行编码时发生的,由于出现了一个未呈现的字符,从而导致特定编码的encode()失败。
例子1 (手动处理UnicodeEncodeError异常)
代码
try:
str(u'éducba')
except UnicodeEncodeError:
print(“Error encoding”)
输出
Error encoding
- ValueError
ValueError通常发生在数学运算中,当一个函数收到一个有效参数的错误值时,会引发ValueError。例如,在一个被编程为接收整数输入的函数中输入一个浮点数将引发一个ValueError。
例子 1 (手动处理ValueError 异常)
代码
def add_numbers(num1, num2):
result = 0
try:
result = int(num1) + int(num2)
except ValueError:
print('Must be an integer!')
else:
return result
add_numbers(10, 20)
add_numbers(1, a)
输出
30
Must be an integer!
- ZeroDivisionError:
ZeroDivisionError是一个内置的Python异常,每当一个数字被0整除时就会引发这个异常。
例子 1 (手动处理零除错误异常)
代码
def divide(x, y):
try:
# Floor Division : Gives only Fractional
# Part as Answer
result = x // y
except ZeroDivisionError:
print("Sorry! You are dividing by zero ")
else:
print("Your answer is: ", result)
#Look at parameters and note the working of the Program
divide(3, 2)
divide(3, 0)
输出
Your answer is: 1
Sorry! You are dividing by zero
Else 语句示例
在前面的例子中,我们看到不同类型的异常是如何被捕获的。然而,实现一个没有错误的程序是任何程序员的最终目标。因此,下面的例子简要描述了程序无错误运行时的情况。
例1 (成功的'try'执行)
代码
#No exception will be raised so the code will be executed without interruption
try:
print("Hello")
except:
print("Something went wrong")
else:
print("Nothing went wrong")
输出
Hello
例2 (成功的 "else "执行)
代码
#No exception will be raised so the code will be executed without interruption
try:
x = 2
if(x>2):
print("Hello")
except:
print("Something went wrong")
else:
print("Nothing went wrong")
输出
Nothing went wrong
对比这两个例子,可以看出输出是不同的。这是由于两个例子中的条件都得到了满足。在第一个例子中,try语句的条件被满足,因此它被执行。然而,在例2中,可以看到条件(x>2)没有被满足,因此*"else "*代码块被执行。值得注意的是,只有在没有错误(异常)的情况下,流程控制的这种变化才有可能。
关键说明
- try "块用于测试一个代码块是否有错误。
- except "块用于处理错误。
- else "块用于在没有错误的情况下执行代码。
问题
- 什么是捕获?
- 在处理异常时使用什么语句?
- 有多少种类型的异常?