Python 有两种错误很容易辨认:语法错误和异常。
语法错误
下面的例子中的问题是print()前面缺少一个冒号:
>>> while True print('Hello world')
File "<stdin>", line 1, in ?
while True print('Hello world')
^
SyntaxError: invalid syntax
异常
1,异常是导致程序中断运行的一种指令流,当异常发生的时候,如果没有进行良好的处理,则程序就会中断执行。(即便 Python 程序的语法是正确的,在运行它的时候,也有可能发生错误。)
>>> 10 * (1/0) # 0 不能作为除数,触发异常
Traceback (most recent call last):
File "<stdin>", line 1, in ?
ZeroDivisionError: division by zero
>>> 4 + spam*3 # spam 未定义,触发异常
Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: name 'spam' is not defined
>>> '2' + 2 # int 不能与 str 相加,触发异常
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate str (not "int") to str
异常处理
2,异常处理的关键字为 try 、 except 、 finally 、 else ,在 try 语句中捕捉异常(如果没有异常,则执行 else 语句);然后在 except 中处理异常; finally 作为异常的统一出口,不管是否发生异常,都要执行此段代码。
1)try/except
try:
result=10/0
print("数学计算")
except ZeroDivisionError as err:
print("出现异常")
2)try/except...else
当try语句中定义的代码不会产生任何异常时,在try语句中执行完毕会自动执行else语句。
try:
result=10/0
print("数学计算")
except ZeroDivisionError as err:
print("出现异常")
else:
print("程序未出现异常")
3)try-finally 语句
在整个异常处理过程中,无论是否出现异常,最终都会执行finally语句块中的代码,而此代码将成为异常的统一出口。
try:
result=10/0
print("数学计算")
except ZeroDivisionError as err:
print("出现异常")
else:
print("程序未出现异常")
finally:
print("异常统一出口")
5)处理多个异常
一个程序代码有可能会产生多种类型的异常。
try:
a=int(input("请输入第一个数字"))
b=int(input("请输入第一个数字"))
result=a/b
print("数学计算")
except ZeroDivisionError as err:
print("出现异常:%s"%err)
except ValueError as err:
print("出现异常:%s"%err)
else:
print("程序未出现异常")
finally:
print("异常统一出口")
4)抛出异常
先验知识:使用Exception类捕获异常——无论出现任何异常,都可以使用同一个except语句进行异常处理。
3,Python中异常的最大父类是 BaseException ,其中 Exception 是程序运行中出现的主要异常。
4.发生异常后, Python 虚拟机会自动产生一个异常类的实例化对象,并匹配相应的 except 语句中的异常类型,由于对象多态性的支持,所有产生的异常类实例都可以通过 Exception 接收。
try:
a=int(input("请输入第一个数字"))
b=int(input("请输入第一个数字"))
result=a/b
print("数学计算")
except Exception as err:
print("出现异常:%s"%err)
else:
print("程序未出现异常")
finally:
print("异常统一出口")
Python 使用 raise 语句抛出一个指定的异常。
5.在 Python 中除了可以自动实例化异常类对象之外,也可以利用 raise 手工抛出异常。
#第一种——指定了要被抛出的异常。
x = 10
if x > 5:
raise Exception('x 不能大于 5。x 的值为: {}'.format(x))
Traceback (most recent call last):
File "test.py", line 3, in <module>
raise Exception('x 不能大于 5。x 的值为: {}'.format(x))
Exception: x 不能大于 5。x 的值为: 10
#第二种——指定了要被抛出的异常。
try:
raise NameError('HiThere') # 模拟一个异常。
except NameError:
print('An exception flew by!')
An exception flew by!
#第三种——如果你只想知道这是否抛出了一个异常,并不想去处理它,那么一个简单的 raise 语句就可以再次把它抛出。
try:
raise NameError('HiThere') # 模拟一个异常。
except NameError:
print('An exception flew by!')
raise
An exception flew by!
Traceback (most recent call last):
File "<stdin>", line 2, in ?
NameError: HiThere
5)用户自定义异常
为了明确地描述与业务相关的异常,实际项目开发往往会采用自定义异常的形式,使用特定的类来标注异常。
通过创建一个新的异常类来拥有自己的异常。异常类继承自 Exception 类,可以直接继承,或者间接继承。
>>> class MyError(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
return repr(self.value)
>>> try:
raise MyError(2*2)
except MyError as e:
print('My exception occurred, value:', e.value)
My exception occurred, value: 4
>>> raise MyError('oops!')
Traceback (most recent call last):
File "<stdin>", line 1, in ?
__main__.MyError: 'oops!'
6)with关键字
with 语句实现原理建立在上下文管理器之上。上下文管理器是一个实现 __enter__ 和 __exit__ 方法的类。使用 with 语句确保在嵌套块的末尾调用 __exit__ 方法。这个概念类似于 try...finally 块的使用。
换句话说:with语句定义了一个对象的上下文管理,在此结构执行时会自动调用__enter__()进行上下文初始化,当调用结束后也会自动调用 __exit__()释放相应资源。
#最开始的代码
file = open('./test_runoob.txt', 'w')
file.write('hello world !')
file.close()
以上代码如果在调用 write 的过程中,出现了异常,则 close 方法将无法被执行,因此资源就会一直被该程序占用而无法被释放。
#改进版
file = open('./test_runoob.txt', 'w')
try:
file.write('hello world')
finally:
file.close()
以上代码我们对可能发生异常的代码处进行 try 捕获,发生异常时执行 except 代码块,finally 代码块是无论什么情况都会执行,所以文件会被关闭,不会因为执行异常而占用资源。
#使用with关键字
with open('./test_runoob.txt', 'w') as file:
file.write('hello world !')
使用 with 关键字系统会自动调用 f.close() 方法, with 的作用等效于 try/finally 语句是一样的。
7)assert
Python assert(断言)用于判断一个表达式,在表达式条件为 false 的时候触发异常。
assert expression
等价于:
if not expression:
raise AssertionError
实例:
>>> assert True # 条件为 true 正常执行
>>> assert False # 条件为 false 触发异常
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError
>>> assert 1==1 # 条件为 true 正常执行
>>> assert 1==2 # 条件为 false 触发异常
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError
>>> assert 1==2, '1 不等于 2'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError: 1 不等于 2
>>>