编程-PythonPythonpython

python 异常处理 exceptions

2021-11-26  本文已影响0人  虐心笔记

一、Excetion

Python最强大的结构之一就是它的异常处理能力,所有的标准异常都使用类来实现。
BaseExcetion 类是一切异常类的基类,自定义的异常类型必须直接或间接的继承自BaseExcetion类。
在程序运行的过程中,如果发生了错误,可以事先约定返回一个错误代码,这样,就可以知道是否有错,以及出错的原因。


异常相关:
try-except: 捕获(接收)异常并进行对应处理或者终止程序。
finally : 最终要执行的语句,常用于清理操作。
raise : 抛出异常对象,可以抛出指定自定义异常。
assert : 断言对象, FALSE则抛出AssertionError异常。
with: 上下文管理


1. 语法错误

语法错误,也称为解析错误,初学者在学习 Python 时会经常遇到的错误类型

impor jmespath

  File "C:/Users/lenovo/PycharmProjects/job/httpRunner_demo/utils/json_parser.py", line 110
    impor jmespath
                 ^
SyntaxError: invalid syntax

Process finished with exit code 1

无错误提示中显示一个小“箭头”,指向检测到错误的行。错误是由(或至少检测到)箭头前面的标记引起的:
以便知道在输入来自脚本的情况下要查找的位置。显然这里是因为import关键字错误导致的。

2. 异常

异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行。
即使语句或表达式在语法上是正确的,当执行它时也可能导致错误。

print(test_json)

Traceback (most recent call last):
  File "C:/Users/lenovo/PycharmProjects/job/httpRunner_demo/utils/json_parser.py", line 122, in <module>
    d = jmespath.search('data.phones', test_json)
NameError: name 'test_json' is not defined

Process finished with exit code 1

异常的抛出机制:

注意:虽然大多数错误会导致异常,但一个异常不一定代表错误,有时候它们只是一个警告,有时候它们可能是一个终止信号,比如退出循环等。

3. 处理异常 try...except

捕捉异常可以使用try/except语句。try/except语句用来检测try语句块中的错误,从而让except语句捕获异常信息并处理。
ps:如果你不想在异常发生时结束你的程序,只需在try里捕获它。

try:
    10/0
except Exception as e:
    print(f'print("Oops!  {e}  Try again...")')
Oops!  division by zero  Try again...

Process finished with exit code 0

4. 引发异常raise

直接抛出指定的异常: raise [Exception [, args [, traceback]]]

>>> raise NameError('Hi There')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: Hi There

唯一参数 raise 指示要引发的异常。这必须是异常实例或异常类(派生自 的类Exception)。
如果传递了一个异常类,它将通过不带参数调用其构造函数来隐式实例化,如果您需要确定是否引发了异常但不打算处理它,则该raise语句的更简单形式直接抛。

6. 用户定义的异常

通过创建一个新的异常类,程序可以命名它们自己的异常。异常应该是典型的继承自Exception类,通过直接或间接的方式。
注意:自定义异常只能由自己抛出,python解释器无法识别用户自定义异常

class CustomError(Exception):
    def __init__(self, error):
        super().__init__(self)
        self.error_info = error

    def __str__(self):
        return self.error_info

    def __repr__(self):
        return self.error_info


if __name__ == '__main__':
    try:
        raise CustomError('! CustomError')
    except CustomError as e:
        print(e)
        raise 
Traceback (most recent call last):
! CustomError
  File "C:/Users/lenovo/PycharmProjects/job/httpRunner_demo/utils/json_parser.py", line 119, in <module>
    raise CustomError('! CustomError')
__main__.CustomError: ! CustomError

Process finished with exit code 1

下面参考 httprunner2 框架中对 exceptions.py 的封装

class MyBaseFailure(Exception):
    """ failure type exceptions, these exceptions will mark test as failure """
    pass


class ParseTestsFailure(MyBaseFailure):
    pass


class ValidationFailure(MyBaseFailure):
    pass


class ExtractFailure(MyBaseFailure):
    pass
8. 上下文管理操作

with表达式其实是try...finally的简写形式。但是又不是全相同。

上下文管理协议(Context Management Protocol):包含方法 enter()和exit(),支持该协议的对象要实现这两个方法。
上下文管理器(Context Manager):支持上下文管理协议的对象,这种对象实现了enter()和exit()方法。上下文管理器定义执行with语句时要建立的运行时上下文,负责执行with语句块上下文中的进入与退出操作。通常使用with语句调用上下文管理器,也可以通过直接调用其方法来使用。

表达式:with EXPR as VAR : SUITE

class SqlHelper(object):
    def __init__(self, config):
        self.connect = pymysql.connect(config)
        self.connect.autocommit(True)

    def __enter__(self):
        self.cursor = self.connect.cursor(cursor=pymysql.cursors.DictCursor)
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.cursor.close()
        self.connect.close()
        
if __name__ == '__main__':
    # 上下文管理方式执行
    with SqlHelper(config) as db:
        result = db.operation(sql)
        print(result)
上一篇 下一篇

猜你喜欢

热点阅读