1. 异常
即便 python 程序的语法是正确的,在运行它的时候,也有可能发生错误。运行期检测到的错误被称为异常。
# int不能与str相加, 触发异常
print(2+'2')
# 0 不能作为除数, 触发异常
print(1/0)
# sum未定义, 触发异常
print(num)
异常以不同的类型出现,这些类型都作为信息的一部分打印出来: 例子中的类型有 ZeroDivisionError,NameError 和 TypeError。
2. try…except…
(1)
异常捕捉可以使用 try…except…语句
# 先看一个案例.
# 因为无法转换成int型数据, 所以抛出异常, 程序直接终止.
# 如果加上异常处理, 那么程序便不会由异常的产生而终止, 而是继续执行, 见下面案例.
print(int('2ss'))
print('HelloWorld')
# 让用户输入一个合法的整数, 如果输入的无法进行无法转换成int型数据, 那么将抛出异常ValueError,
# 此异常被捕获. 由于我们做了异常处理, 所以即使发生异常, 程序也不会直接退出.
while True:
try:
value = int(input("please input a number:> "))
break
except ValueError:
print("occur error.")
(2)
try…except…的工作流程
try语句按照如下方式工作:
首先,执行try子句(在关键字try和关键字except之间的语句);
如果没有异常发生,忽略except子句,try子句执行后继续其他代码的执行;
如果在执行try子句的过程中发生了异常,那么try子句余下的部分将被不会被执行
;
如果异常的类型和except之后的名称相符,那么对应的except子句将被执行;
如果一个异常没有与任何的except匹配,那么这个异常将会传递给上层的try中;
(3)
多异常处理
一个 try语句可能包含多个except子句
,分别来处理不同的特定的异常
。最多只有一个分支会被执行。
处理程序将只针对对应的try子句中的异常进行处理,而不是其他的try的处理程序中的异常。
一个except子句可以同时处理多个异常,这些异常将被放在一个括号里成为一个元组
。
except (RuntimeError, TypeError, NameError):
pass
最后一个except子句可以忽略异常的名称,它将被当作通配符使用(可以捕获所有异常)
。你可以使用这种方法打印一个错误信息,然后再次把异常抛出。
# 试图打开一个不存在的文件, 将触发OSError异常.
import sys
try:
file = open("report.txt")
context = file.readline()
i = int(context.strip())
except OSError as err:
print("OS error: {0}.".format(err))
except ValueError:
print("Could not convert data to an integer.")
except:
print("Unexpected error:", sys.exc_info())
raise
3. try…except…else…
try…except… 语句还有一个可选的else子句
,如果使用这个子句,那么必须放在所有的except子句之后
。else子句将在try子句
没有发生任何异常的时候执行。
# else子句将在没有任何异常发生时执行.
def fail(code):
if(code):
return 1/1
else:
return 1/0
try:
fail(1)
#fail(0)
except ZeroDivisionError as err:
print('handle run-time error:> ', err)
else:
print('no error.')
4. try-finally…
try-finally 语句无论是否发生异常都将执行最后的代码
。
# 即使发生了异常, finally子句也会被执行.
def fail(code):
if(code):
return 1/1
else:
return 1/0
try:
fail(0)
except ZeroDivisionError as err:
print('handle run-time error:> ', err)
else:
print('no error.')
finally:
print("不管有无异常, 都会被执行.")
5. 抛出异常raise
python 使用 raise
语句抛出一个指定的异常。
raise语法格式如下:raise [Exception [, args [, traceback]]]*
# 以下案例将抛出异常.
x = 10
if x > 5:
raise Exception("x不能大于5.")
raise 唯一的一个参数
指定了要被抛出的异常。它必须是一个异常的实例或者是异常的类
(也就是 Exception 的子类)。
如果你只想知道这是否抛出了一个异常,并不想去处理它
,那么一个简单的 raise 语句就可以再次把它抛出
。
try:
raise NameError('抛出异常.')
except NameError:
print('截获异常.')
raise
6. 自定义异常
可以通过创建一个新的异常类来拥有自己的异常
。异常类继承自 Exception 类
,可以直接继承,或者间接继承。
# 自定义异常类MyError, 继承自Expection类.
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 error:
print('My Exception occurred, code is:> ', error.value)
7. with关键字
python 中的 with 语句用于异常处理,封装了 try…except…finally…
编码范式,提高了易用性。
with 语句使代码更清晰、更具可读性, 它简化了文件流等公共资源的管理。
在处理文件对象时使用 with 关键字是一种很好的做法
。
接下来看一个案例分析:>
# 1.
# 不使用 with,也不使用 try…except…finally.
# 以上代码如果在调用write()的过程中出现了异常, 则close()方法将无法被执行.
# 因此资源就会一直被该程序占用而无法被释放.
file = open('./temp.txt', 'w')
file.write('hello world !')
file.close()
# 2.
# 接下来使用 try…except…finally…来改进代码.
# 以上代码我们对可能发生异常的代码处进行try捕获, 发生异常时执行except代码块,
# finally代码块是无论什么情况都会执行,所以文件会被关闭,不会因为执行异常而占用资源.
# Notice: [except:] 后面没有跟异常名, 是一个通配符, 表示捕获所有异常.
file = open('./temp.txt', 'w')
try:
file.write('hello world !')
except: # 表示捕获所有异常
...
finally:
file.close()
# 3.
# 最后使用with关键字.
# 使用with关键字系统会自动调用f.close()方法, with的作用等效于try/finally语句是一样的.
with open('./temp.txt', 'w') as file:
file.write('hello world !')
with语句原理:
with 语句实现原理建立在上下文管理器之上。
上下文管理器是一个实现 enter 和 exit 方法的类。
使用 with 语句确保在嵌套块的末尾调用 exit 方法。
这个概念类似于 try…finally 块的使用。
with open('./temp.txt', 'w') as my_file:
my_file.write('hello world !')
以上实例将 hello world! 写到 ./temp.txt 文件中去。
在文件对象中定义了 __enter__
和 __exit__
方法,即文件对象也实现了上下文管理器,首先调用 __enter__
方法,然后执行 with 语句中的代码,最后调用 __exit__
方法。 即使出现错误,也会调用 __exit__
方法,也就是会关闭文件流。
8. assert断言
python assert(断言)用于判断一个表达式,在表达式条件为 false 的时候触发异常
。
断言可以在条件不满足程序运行的情况下直接返回错误
,而不必等待程序运行后出现崩溃的情况,例如我们的代码只能在 Linux 系统下运行,可以先判断当前系统是否符合条件。
num = 5
assert num > 5 # num必须大于5, 否则触发异常
以下实例判断当前系统是否为 Linux,如果不满足条件则直接触发异常,不必执行接下来的代码:
import sys
assert ('linux' in sys.platform), "该代码只能在 Linux 下执行"
print("HelloWorld.")
print("HelloWorld.")
print("HelloWorld.")