十7、深刻Python异常处理

「@Author:BY Runsen」git

在Python 中的错误和异常是什么?github

一般来讲,程序中的错误至少包括两种,一种是语法错误,另外一种则是异常。web

语法错误

所谓语法错误,你应该很清楚,也就是你写的代码不符合编程规范,没法被识别与执行,好比下面这个例子的语法错误面试

下面的代码没法被识别和执行数据库

if name is not None
    print(name)

上面的代码If 语句漏掉了冒号,不符合 Python 的语法规范,因此程序就会报错invalid syntax编程

异常

异常则是指程序的语法正确,也能够被执行,但在执行过程当中遇到了错误,抛出了异常。json

好比,最多见的除数不能为0。变量没有定义。数据类型的运算。小程序

10 / 0
Traceback (most recent call last):
  File "<stdin>", line 1in <module>
ZeroDivisionError: integer division or modulo by zero

order * 2
Traceback (most recent call last):
  File "<stdin>", line 1in <module>
NameError: name 'order' is not defined

1 + [12]
Traceback (most recent call last):
  File "<stdin>", line 1in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'list'

上面报的是常见的报错,好比ZeroDIvision NameError 和 typeError微信

还有不少其余异常的类型如keyError 字典的键找不到和FileNotFoundError 文件不存在app

try except

使用Python的异常处理语句,能够很是优雅地处理发生的异常。

下面是Python的异常处理语句的模板语法

try:
    # 可能触发异常的语句块
except:  
    # 这里执行异常处理的相关代码,打印输出等
else:
    # 若是没有异常则执行else中的代码
finally:
    # 无论代码是否异常,都会执行,通常是资源的关闭和释放

首先,检测try语句块中的错误,except语句捕获异常信息并处理。若是在try子句执行时没有发生异常,Python将执行else语句后的语句,而后控制流经过整个try语句。

好比看下面的例子。

try:
    print(a*2)
except TypeError:
    print("TypeError")
except:
    print("Not Type Error & Error noted")
    
Not Type Error & Error noted

因为a没有定义,报的是NameError而不是TypeError。异常最终被except:部分的程序捕捉。

这里,Runsen补充一下很是重要的知识点:

抛出异常

抛出异常模板:raise 异常类名(附加异常信息) 。下面是示例代码:

s = "RunsenRunsen"
try:
    if len(s) > 10:
        raise Exception("超过10个字符")
except Exception as err:
    print(err)
    
超过10个字符

有时产生的异常,不想在当前处理,那么就可使用raise抛出异常。下面是示例代码:

def division():
    a = float(input('输入被除数:'))
    b = float(input("输入除数:"))
    if a < 0 or b < 0:
        raise Exception("我是Runsen,要求:输入的数不能小于0。"#出现负数抛出异常。
    c = a / b
    print(a,'÷',b,'=',c)
    
try:
    division()
except Exception as d:
    print('出错了,',d)
    
运行结果:
输入被除数:5
输入除数:-1
出错了, 我是小学生,输入的数不能小于0。
输入被除数:5
输入除数:0
出错了, float division by zero

万能异常

由于异常分了不一样的种类,若是不知道,那么使用exception异常处理就足够了,它能够接收任何异常

value = 'hello'
try:
    int(value)
#万能异常处理  
except Exception as e:
    print(e)

自定义异常

实际开发中,有时候系统提供的异常类型不能知足开发的需求。这时候你能够经过建立一个新的异常类来拥有本身的异常。异常类继承自 Exception 类,能够直接继承,或者间接继承。

# 自定义异常类 MyError ,继承普通异常基类 Exception
class MyError(Exception):
        def __init__(self, value):
            self.value = value
        def __str__(self):
            return repr(self.value)
try:
    num = input("请输入数字:")
    if not num.isdigit():  # 判断输入的是不是数字
        raise MyError(num)  # 输入的若是不是数字,手动指定抛出异常
except MyError as e:
    print("MyError:请输入数字。您输入的是:", e.value)

请输入数字:1
请输入数字:Runsen
MyError:请输入数字。您输入的是:Runsen

扩展

大型社交网站的后台,须要针对用户发送的请求返回相应记录。用户记录每每储存在 key-value 结构的数据库中,每次有请求过来后,咱们拿到用户的 ID,并用 ID 查询数据库中此人的记录,就能返回相应的结果。而数据库返回的原始数据,每每是 json string 的形式,这就须要咱们首先对 json string 进行 decode(解码),你可能很容易想到下面的方法:

import json
raw_data = queryDB(uid) # 根据用户的 id,返回相应的信息。queryDB这里是一个函数
data = json.loads(raw_data)

上面的代码是否是就足够呢?

json.loads()函数中,若是输入的字符串不符合规范,那么就没法解码,就会抛出异常。

raw_data必定是json吗?,所以写以前就应该考虑如何处理异常

try:
    data = json.loads(raw_data)
except JSONDecodeError as err:
    print('JSONDecodeError: {}'.format(err))

「附件:异常类列表(来源:菜鸟教程)」

异常名称 描述


BaseException 全部异常的基类
SystemExit 解释器请求退出
KeyboardInterrupt 用户中断执行(一般是输入^C)
Exception 常规错误的基类
StopIteration 迭代器没有更多的值
GeneratorExit 生成器(generator)发生异常来通知退出
StandardError 全部的内建标准异常的基类
ArithmeticError 全部数值计算错误的基类
FloatingPointError 浮点计算错误
OverflowError 数值运算超出最大限制
ZeroDivisionError 除(或取模)零 (全部数据类型)
AssertionError 断言语句失败
AttributeError 对象没有这个属性
EOFError 没有内建输入,到达EOF 标记
EnvironmentError 操做系统错误的基类
IOError 输入/输出操做失败
OSError 操做系统错误
WindowsError 系统调用失败
ImportError 导入模块/对象失败
LookupError 无效数据查询的基类
IndexError 序列中没有此索引(index)
KeyError 映射中没有这个键
MemoryError 内存溢出错误(对于Python 解释器不是致命的)
NameError 未声明/初始化对象 (没有属性)
UnboundLocalError 访问未初始化的本地变量
ReferenceError 弱引用(Weak reference)试图访问已经垃圾回收了的对象
RuntimeError 通常的运行时错误
NotImplementedError 还没有实现的方法
SyntaxError Python 语法错误
IndentationError 缩进错误
TabError Tab 和空格混用
SystemError 通常的解释器系统错误
TypeError 对类型无效的操做
ValueError 传入无效的参数
UnicodeError Unicode 相关的错误
UnicodeDecodeError Unicode 解码时的错误
UnicodeEncodeError Unicode 编码时错误
UnicodeTranslateError Unicode 转换时错误
Warning 警告的基类
DeprecationWarning 关于被弃用的特征的警告
FutureWarning 关于构造未来语义会有改变的警告
OverflowWarning 旧的关于自动提高为长整型(long)的警告
PendingDeprecationWarning 关于特性将会被废弃的警告
RuntimeWarning 可疑的运行时行为(runtime behavior)的警告
SyntaxWarning 可疑的语法的警告
UserWarning 用户代码生成的警告

本文已收录 GitHub,传送门~[1] ,里面更有大厂面试完整考点,欢迎 Star。



Reference

[1]

传送门~: https://github.com/MaoliRUNsen/runsenlearnpy100


今天的文章到这里就结束了,若是喜欢本文的话,请来一波素质三连,给我一点支持吧(关注、在看、点赞)。

更多的文章

点击下面小程序


- END -




本文分享自微信公众号 - Python之王(sen13717378202)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。

相关文章
相关标签/搜索