23. 异常处理机制

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

1. 异常

即便 python 程序的语法是正确的在运行它的时候也有可能发生错误。运行期检测到的错误被称为异常。

# int不能与str相加, 触发异常
print(2+'2')
# 0 不能作为除数, 触发异常
print(1/0)
# sum未定义, 触发异常
print(num)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

异常以不同的类型出现这些类型都作为信息的一部分打印出来 例子中的类型有 ZeroDivisionErrorNameError 和 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 语句实现原理建立在上下文管理器之上。
上下文管理器是一个实现 enterexit 方法的类。
使用 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.")

在这里插入图片描述

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6