凡事即可错,但总有补救办法!
在编写Python程序时,经常回因为错误导致程序立即终止。在Python中,错误可以是语法错误或异常。
接下来我们将介绍python的常见异常以及如何处理错误,主要覆盖一下知识点:
- 语法错误 vs. 异常
- 如何引发异常
- 如何处理异常
- 最常见的内置异常
- 如何定义你自己的异常
语法错误 - Syntax Errors
语法错误发生在解析器检测到一个语法错误的语句。 一个语法错误可以是一个拼写错误,缺少括号,没有换行(请看下面的代码),或错误的缩进(这将实际上抛出它自己的IndentationError
,但是它是一个SyntaxError
的子类)。
代码:
a = 5
print(a)
结果:
File "/usercode/main.py", line 1
a = 5 print(a)
^
SyntaxError: invalid syntax
异常 - Exceptions
即使语句是正确的,也可能在执行时引发错误。 这是一个异常错误。有几个不同的错误类,例如尝试将一个数字和字符串相加将引发一个TypeError
。
代码:
a = 5 + '10'
结果:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/usercode/main.py in <module>
----> 1 a = 5 + '10'
TypeError: unsupported operand type(s) for +: 'int' and 'str'
抛出异常 - Raising an Exception
如果你想在某个条件发生时强制抛出异常,可以使用raise
关键字。
代码:
x = -5
if x < 0:
raise Exception('x不可以是负数')
结果:
---------------------------------------------------------------------------
Exception Traceback (most recent call last)
/usercode/main.py in <module>
1 x = -5
2 if x < 0:
----> 3 raise Exception('x不可以是负数')
Exception: x不可以是负数
你也可以使用assert
语句,它会在你的断言为不为真时抛出AssertionError
。 这样,你可以主动测试一些条件,必须被满足而不是等待你的程序意外地崩溃。
assert
也被用于单元测试。
代码:
x = -5
assert (x >= 0), 'x不是负数'
# --> 在x不是负数时,抛出AssertionError
结果:
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
/usercode/main.py in <module>
1 x = -5
----> 2 assert (x >= 0), 'x不是负数'
3 # --> 在x不是负数时,抛出AssertionError
AssertionError: x不是负数
处理异常 - Handling Exceptions
你可以使用try-except
块来捕获和处理异常。 如果你捕获了异常,那么程序不会终止,可以继续执行。
# 这将捕获所有可能的异常
try:
a = 5 / 0
except:
print('发生了一些错误!')
# 你也可以捕获异常的类型
try:
a = 5 / 0
except Exception as e:
print(e)
# 它是一个好习惯,指定你想捕获的异常类型
# 因为,你必须知道可能的错误
try:
a = 5 / 0
except ZeroDivisionError:
print('仅仅捕获了除零异常,而没有捕获其他的异常。')
# 你可以在一个try块中运行多个语句,并且捕获不同的可能的异常
try:
a = 5 / 1 # 注意:没有ZeroDivisionError这里
b = a + '10'
except ZeroDivisionError as e:
print('除零错误:', e)
except TypeError as e:
print('类型错误:', e)
结果:
发生了一些错误!
division by zero
仅仅捕获了除零异常,而没有捕获其他的异常。
类型错误: unsupported operand type(s) for +: 'float' and 'str'
else 子句
你可以使用else语句,它在没有发生异常时执行。
代码:
try:
a = 5 / 1
except ZeroDivisionError as e:
print('除零错误:', e)
else:
print('一切正常!')
结果:
一切正常!
finally 子句
你可以使用finally
语句,它总是会执行,无论是否发生异常。 这是为了做一些清理工作。
try:
a = 5 / 1 # 注意:没有ZeroDivisionError这里
b = a + '10'
except ZeroDivisionError as e:
print('发生了除零错误:', e)
except TypeError as e:
print('发生了类型错误:', e)
else:
print('一切正常!')
finally:
print('无论是否发生异常,都会执行的代码')
结果:
发生了类型错误: unsupported operand type(s) for +: 'float' and 'str'
无论是否发生异常,都会执行的代码
内建异常 - built-in Exceptions
你可以在官网查看所有的内建的异常,以下是常见的异常:
- ImportError:如果一个模块不能被导入
- NameError:如果你尝试使用一个未定义的变量
- FileNotFoundError:如果你尝试打开一个不存在的文件或者你指定了错误的路径
- ValueError:当一个操作或者函数接收到一个合适的类型的参数,但是参数的值不合适时,比如尝试从一个列表中移除一个不存在的值
- TypeError:当一个操作或者函数应用了一个不适合的类型的对象时,比如尝试从一个列表中移除一个不存在的值
- IndexError:如果你尝试访问一个不存在的索引
- KeyError:如果你尝试访问一个不存在的键
代码:
# 定义一个函数,打印内置异常
def printErr(code, message):
print(f">>>{message} 演示:\n")
try:
exec(code)
except Exception as e:
print(f""{code}": {e}")
printErr("import not_exist_module", "模块不存在")
printErr("a=not_exist_variable", "变量不存在")
printErr("f = open('not_exist_file.txt')", "文件不存在")
printErr("a=[0,1,2];a.remove(3)", "值错误")
printErr("a = 5 + '10'", "类型错误")
printErr("a = [0, 1, 2]; value = a[5]", "索引错误")
printErr("my_dict = {'name': 'Max', 'city': 'Boston'}; age = my_dict['age']", "键错误")
结果:
>>> import not_exist_module: 模块不存在
No module named 'not_exist_module'
>>> a=not_exist_variable: 变量不存在
name 'not_exist_variable' is not defined
>>> f = open('not_exist_file.txt'): 文件不存在
[Errno 2] No such file or directory: 'not_exist_file.txt'
>>> a=[0,1,2];a.remove(3): 值错误
list.remove(x): x not in list
>>> a = 5 + '10': 类型错误
unsupported operand type(s) for +: 'int' and 'str'
>>> a = [0, 1, 2]; value = a[5]: 索引错误
list index out of range
>>> my_dict = {'name': 'Max', 'city': 'Boston'}; a = my_dict['age']: 键错误
'age'
自定义异常 - Define your own Exceptions
你也可以定义你自己的异常类,但应该继承自内建的Exception
类。
大多数异常都以Error结尾的,与标准异常相似,异常类也可以定义为任何类型, 但是通常都很简单的,只提供一些属性,允许处理程序提取错误的信息。
代码:
# 定义一个自定义异常类
class ValueTooHighError(Exception):
pass
# 或者给处理程序添加更多的信息
class ValueTooLowError(Exception):
def __init__(self, message, value):
self.message = message
self.value = value
def test_value(a):
if a > 1000:
raise ValueTooHighError('值太大了')
if a < 5:
raise ValueTooLowError('值太小了', a) # 注意这里的构造函数参数为2个
return a
try:
test_value(1)
except ValueTooHighError as e:
print(e)
except ValueTooLowError as e:
print(e.message, '值为:', e.value)
结果:
值太小了 值为: 1
总结
本文简要介绍python常见的错误异常,以及如何对异常进行处理。异常是编程中百分百会遇到的,正确的捕获异常及处理,可以让程序变的更加的健壮!
感谢你阅读本文。如果觉得这篇文章对你有帮助,欢迎大家点赞、收藏、支持!
pythontip 出品,Happy Coding!
公众号: 夸克编程