自学内容网 自学内容网

[Python学习日记-71] Python 中的异常处理

[Python学习日记-71] Python 中的异常处理

简介

什么是异常

异常的种类

异常处理

简介

        报错我们并不陌生,在编写程序与运行程序的时候经常会遇到报错(报错其实就是程序运行时发生错误的信号,基本可以和异常划上等号),这通常会导致程序的终止,导致后面的代码都无法运行,但有时候我们并不想因为一点错误就导致整个程序终止,而是想后面的代码继续运行,这个时候就需要用到 Python 中的异常处理了,在本篇当中我们将了解什么是异常,了解常见的异常种类,并掌握如何使用异常处理。

什么是异常

        异常就是程序运行时发生错误的信号(在程序出现错误时,则会产生一个异常,若程序没有处理它,则会抛出该异常,程序的运行也随之终止),在 Python 中错误触发的异常如下

        而错误分为两种,一是语法错误,二是逻辑错误,详细如下:

1、语法错误

        这种错误根本过不了 Python 解释器的语法检测,必须在程序执行前就进行更正

# 语法错误示范一
if

# 语法错误示范二
def test:
    pass

# 语法错误示范三
class Foo
    pass

# 语法错误示范四
print(hai

代码输出如下:

2、逻辑错误

        这种错误可能程序能正常运行,但是程序运行的过程中可能会出现错误导致程序终止

# TypeError:int 类型不可选代
for i in 3:
    pass

# ValueError
num = input(">>: ")    # 输入 hello
int(num)

# NameError
aaa

# IndexError
l = ['jove','aa']
l[3]

# KeyError
dic = {'name':'jove'}
dic['age']

# AttributeError
class Foo:pass
Foo.x

# ZeroDivisionError:无法完成计算
res1 = 1/0
res2 = 1 + 'str'

代码输出如下:

异常的种类

        在 Python 中不同的异常可以用不同的类型(Python 中统一了类与类型,类型即类)去标识,一个异常标识一种错误,下面我们来介绍一下各种异常。

一、常见异常

异常类型描述
AttributeError试图访问一个对象没有的属性,例如 Foo.x,但是 Foo 没有属性 x
IOError输入/输出异常,基本上是无法打开文件
ImportError无法引入模块或包,基本上是路径问题或名称错误
IndentationError语法错误的子类,可能代码没有正确对齐之类的
IndexError下标索引超出序列边界,例如当 x 只有三个元素,却试图访问 x[5]
KeyError试图访问字典里不存在的键
KeyboardInterrupt程序运行时 Ctrl+C 被按下
NameError使用一个还未被赋予对象的变量
SyntaxErrorPython 代码非法,代码不能编译,也可以说是语法错误
TypeError传入对象类型与要求的不符合
UnboundLocalError试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,导致你以为正在访问它
ValueError传入一个调用者不期望的值,即使值的类型是正确的

二、其他异常

异常类型描述
ArithmeticError表示数学运算错误的异常,它是 ZeroDivisionError(除数为零错误)、FloatingPointError(浮点运算错误)、OverflowError(数值运算超出范围错误)、UnderflowError(数值运算结果过小错误)、AssertionError(断言错误)和 SystemExit(程序退出错误)的基类
AssertionError通常在使用 assert 语句时触发,用于检查某个条件是否为真,如果条件为假,就会抛出 AssertionError 异常
BaseException它是最通用的异常类型,在 Python 中是所有异常的基类
BufferError表示发生了与缓冲区操作相关的错误
BytesWarning表示在 byte 或 bytearray 的操作中发生了潜在的问题,例如将 bytes 或 bytearray 对象视为字符串对象进行操作
DeprecationWarning用于警告某个功能、模块或方法已被弃用,即将在未来的版本中被移除。当程序中使用了被弃用的功能时,Python 会发出该异常来提醒开发者
EnvironmentError表示基本环境错误,在 Python3 中已被移除,可以用 OSError 来替代
EOFError表示遇到了意外的文件末尾(End of File)
Exception用于捕获并处理各种类型的异常
FloatingPointError表示浮点运算错误,例如 1.0/0 或者对负数进行平方根运算时会触发
FutureWarning用来警告用户有关将来版本中可能发生的变化、废弃方法或可能导致问题的代码,通常不会导致程序中断,但提醒开发者代码可能需要调整或更新
GeneratorExit当一个生成器对象被关闭时,但还有未处理的 yield 语句时会抛出该异常
ImportWarning表示在导入模块时出现的警告,可能模块或包中的内容有致潜在的问题或错误
LookupError用于处理查找相关的错误,它是 IndexError、KeyError、NameError、AttributeError、ImportError 这类查找类型的基类
MemoryError表示内存不足的错误
NotImplementedError表示某个方法或函数的实现尚未完成
OSError表示与操作系统相关的错误,例如文件找不到、文件无法打开、权限不足等都会抛出该错误
OverflowError表示数值溢出错误,例如使用 int 类型来表示一个大于最大整数值的数时就会抛出该错误
PendingDeprecationWarning表示某个功能在未来版本中可能会被弃用
RuntimeError表示在运行时发生的错误,通常用于指示代码中的逻辑错误
RuntimeWarning表示在运行时发生了一个警告,并不会立即终止程序运行
StandardError异常类型的基类,在 Python3 已被移除,被 BaseException 代替
StopIteration迭代器对象的异常,在迭代过程中用来表示迭代结束的信号
SyntaxWarning语法警告,Python 解释器在检测到代码中存在一些不符合语法规范的写法
SystemError表示一个内部错误,通常是由于解释器自身出现问题而引发的异常
SystemExit表示程序正常地退出
TabError表示在代码中出现了 Tab 和空格混用的错误
UnicodeDecodeError将字节数据解码为 Unicode 字符时出现的错误
UnicodeEncodeError将字符串进行编码时发生错误会出现的错误
UnicodeError表示 Unicode 编码相关的错误,例如包含无效的 Unicode 字符、解码错误、编码错误等
UnicodeTranslateError表示在转换字符串时出现的 Unicode 转换错误,例如目标编码不支持源字符串中的某些字符、源字符串包含无法映射到目标编码的字符、源字符串包含无效的编码序列
UnicodeWarning表示 Unicode 相关的警告,它是 UnicodeError 的子类
UserWarning表示一些用户定义的警告
Warning警告,指在代码执行过程中发生了一些不太严重的问题,但仍然需要引起注意
ZeroDivisionError表示除法运算(/ 或者 //)错误,例如10/0 或者 100//0

异常处理

一、初识 try...except...

        为了保证程序的健壮性与容错性,即在遇到错误时程序不会崩溃,我们需要对异常进行处理,而异常处理分为两种情况,一是错误发生的条件是可预知的,二是错误发生的条件是不可预知的,下面我们来看看面对这两种情况应该如何处理

1、如果错误发生的条件是可预知的,我们需要用 if 进行处理:在错误发生之前进行预防

AGE = 10

while True:
    age = input('>>: ').strip()
    if age.isdigit():
        age = int(age)  # 如果这里输入的是非数字的就会出错
        if age > AGE:
            print('太大了')
        elif age < AGE:
            print('太小了')
        elif age == AGE:
            print('刚刚好')
            break
    else:
        print('只能输入数字')

代码输出如下:

2、如果错误发生的条件是不可预知的,则需要用到 try...except...:在错误发生之后进行处理

try...except... 的基本语法为:

try:

        被检测的代码块

except 异常类型:

        try 中一旦检测到指定的异常类型,就执行这里面的代码

a.txt

1111
22
333
444

# try...except是错误已经出现了,但是不让错误呈现出来
f = open('a.txt','r',encoding='utf-8')
try:
    print(next(f),end='')
    print(next(f),end='')
    print(next(f),end='')
    print(next(f),end='')
    print(next(f),end='')
    print(next(f),end='')
except StopIteration:
    print('出错啦')
f.close()

print('=====>1')
print('=====>2')
print('=====>3')

代码输出如下:

二、try...except... 详细用法

1、异常类只能用来处理指定的异常情况,如果非指定异常则无法处理

s1 = 'hello'
try:
    int(s1) # ValueError
except IndexError as e: # 未捕获到异常,程序直接报错
    print(e)

代码输出如下:

2、多分支的异常处理

        被检测的代码块抛出的异常有多种可能性,并且我们需要针对每一种异常类型都定制专门的处理逻辑,如下

try:
    print('=====>1')
    name    # NameError
    print('=====>2')
    l = [1,2,3]
    l[100]  # IndexError
    print('=====>3')
    d = {}
    d['name']   # KeyError
    print('=====>4')
except NameError as e:
    print('----->',e)

except IndexError as e:
    print('----->', e)

except KeyError as e:
    print('----->', e)

print('====>after code')

代码输出如下:

        发生 NameError 错误时

        发生 IndexError 错误时

        发生 KeyError 错误时

        无错误发生时

3、万能的异常处理——Exception

        被检测的代码块抛出的异常有多种可能性,并且我们针对所有的异常类型都只用一种处理逻辑那就可以使用 Exception 来处理所有异常了,如下

try:
    print('=====>1')
    name    # NameError
    print('=====>2')
    l = [1,2,3]
    l[100]  # IndexError
    print('=====>3')
    d = {}
    d['name']   # KeyError
    print('=====>4')
except Exception as e:
    print('异常发生啦: ', e)

print('====>after code')

代码输出如下:

        结合多分支来使用,把  Exception 当做托底的异常处理

try:
    print('=====>1')
    name    # NameError
    print('=====>2')
    l = [1,2,3]
    l[100]  # IndexError
    print('=====>3')
    d = {}
    d['name']   # KeyError
    print('=====>4')
except NameError as e:
    print('----->',e)

except IndexError as e:
    print('----->', e)

except KeyError as e:
    print('----->', e)

except Exception as e:
    print('统一的处理方法')

print('====>after code')

代码输出如下:

4、异常处理的其他机构(else、finally)

try:
    print('=====>1')
    # name
    print('=====>2')
    l = [1,2,3]
    # l[100]
    print('=====>3')
    d = {}
    # d['name']
    print('=====>4')
except NameError as e:
    print('----->',e)

except IndexError as e:
    print('----->', e)

except KeyError as e:
    print('----->', e)

except Exception as e:
    print('统一的处理方法')

else:
    print('在被检测的代码块没有发生异常时执行')

finally:
    print('不管被检测的代码块有无发生异常都会执行')

print('====>after code')

代码输出如下:

        finally 感觉和直接写在 try...except... 外的代码没什么区别,其实它的具体应用是在于回收资源的环节,例如文件操作完成后的 close() 操作,如下

try:
    f=open('a.txt','r',encoding='utf-8')
    print(next(f),end='')
    print(next(f),end='')
    print(next(f),end='')
    print(next(f),end='')

    print(next(f),end='')
    print(next(f),end='')
except StopIteration as e:
    print('----->', e)
finally:
    f.close()

代码输出如下:

5、主动触发异常

class People:
    def __init__(self,name,age):
        if not isinstance(name,str):
            raise TypeError('名字必须传入str类型')
        if not isinstance(age,int):
            raise TypeError('年龄必须传入int类型')

        self.name = name
        self.age = age

p = People('jove','28')

代码输出如下:

6、自定义异常

class MyException(BaseException):
    def __init__(self,msg):
        super(MyException, self).__init__()
        self.msg = msg

    def __str__(self):
        return '<%s>' % self.msg

raise MyException('我自己的异常类型')  # print(obj)

代码输出如下:

注意:代码当中 raise MyException(...) 相当于 print(obj),如果不在 MyException 类当中定义 __str__ 将不会按照我们的设想那样在异常当中显示我们输入的信息

7、断言——assert 条件

info = {}
info['name'] = 'egon'
info['age'] = 18

# 这是断言assert做的事
# if 'name' not in info:
#     raise KeyError('必须有name这个key')
# if 'age' not in info:
#     raise KeyError('必须有age这个key')

assert ('name' in info) and ('age' in info)

if info['name'] == 'egon' and info['age'] == 18:
    print('welcome')

代码输出如下:

        如果 name 和 age 都存在

        如果 name 或者 age 其中一个不存在

8、总结 try...except...

  • 把错误处理和真正的工作分开来
  • 代码更易组织,更清晰,复杂的工作任务更容易实现
  • 程序更安全,不至于由于一些小的错误而使程序意外崩溃

原文地址:https://blog.csdn.net/zjw529507929/article/details/144269241

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!