Python的异常处理

简介: Python的异常处理

异常处理

程序错误分为两种:语法错误 和 异常错误

语法错误:代码没有按照python规定语法去写,发明创造产生的错误 #语法错误抑制不了

异常错误:在代码语法正确的前提下,程序报错就是异常 #异常错误可以抑制

#try…except… 基础语法 用于解决程序异常问题

#raise 可以主动抛异常,异常类可以自定义

异常的分类

IndexError 索引超出序列的范围

KeyError 字典中查找一个不存在的关键字

NameError 尝试访问一个不存在的变量

IndentationError 缩进错误

AttributeError 尝试访问未知的对象属性

StopIteration 迭代器没有更多的值

AssertionError 断言语句(assert)失败

EOFError 用户输入文件末尾标志EOF(Ctrl+d)

FloatingPointError 浮点计算错误

GeneratorExit generator.close()方法被调用的时候

ImportError 导入模块失败的时候

KeyboardInterrupt 用户输入中断键(Ctrl+c)

MemoryError 内存溢出(可通过删除对象释放内存)

NotImplementedError 尚未实现的方法

OSError 操作系统产生的异常(例如打开一个不存在的文件)

OverflowError 数值运算超出最大限制

ReferenceError 弱引用(weak reference)试图访问一个已经被垃圾回收机制回收了的对象

RuntimeError 一般的运行时错误

SyntaxError Python的语法错误

TabError Tab和空格混合使用

SystemError Python编译器系统错误

SystemExit Python编译器进程被关闭

TypeError 不同类型间的无效操作

UnboundLocalError 访问一个未初始化的本地变量(NameError的子类)

UnicodeError Unicode相关的错误(ValueError的子类)

UnicodeEncodeError Unicode编码时的错误(UnicodeError的子类)

UnicodeDecodeError Unicode解码时的错误(UnicodeError的子类)

UnicodeTranslateError Unicode转换时的错误(UnicodeError的子类)

ValueError 传入无效的参数

ZeroDivisionError 除数为零

获取错误行号和文件名(了解)

#(了解)系统底层获取行数和文件名的函数( 只有在程序异常时才能触发 )

def return_errorinfo(n):

import sys

f = sys.exc_info()[2].tb_frame.f_back

if n==1:

return str(f.f_lineno) #返回当前行数

elif n == 2:

return f.f_code.co_filename #返回文件名

1、IndexError 索引超出序列的范围

lst = [1,2,3]
lst[1000]

左边是错误类型,右边是错误的描述

2、KeyError 字典中查找一个不存在的关键字

dic = {"a":1,"b":2}
dic["c"]

3、NameError 尝试访问一个不存在的变量

print(jingtian112312313123123123123123123123123123s)

4、IndentationError 缩进错误

if 5 == 5:

print(2)

5、AttributeError 尝试访问未知的对象属性

class MyClass():
     a = 100
obj = MyClass()
obj.abc

6、StopIteration 迭代器没有更多的值

it = iter(range(3))
res = next(it)
res = next(it)
res = next(it)
res = next(it)

7、AssertionError 断言语句(assert)失败

assert猜的意思 , 叫断言,

如果断言是正确的没有任何反应,代码正常执行

如果是错误的直接报错,终止程序

使用assert断言是学习python一个非常好的习惯,python assert 断言句语格式及用法很简单。在没完善一个程序之前,我们不知道程序在哪里会出错,

与其让它在运行最崩溃,不如在出现错误条件时就崩溃,这时候就需要assert断言的帮助。本文主要是讲 assert 断言的基础知识

python assert断言的作用

python assert断言是声明其布尔值必须为真的判定,如果发生异常就说明表达示为假。可以理解assert断言语句为raise-if-not,用来测试表示式,其返回值为假,就会触发异常。

assert 5 < 3
print(111)

报错后,后面的代码不再执行

异常处理的语法

try … except … 来抑制错误

把有可能报错的代码放到try这个代码块当中,

如果有报错,直接执行except这个代码块

如果没有报错,不执行except这个代码块


在异常处理当中,所有的异常错误类都默认继承 BaseException Exception 普通异常的父类(了解)

我们写except时,不写异常类型,默认都是BaseException

#类型上的子父关系

from collections import Iterator,Iterable
print(issubclass(Iterator, Iterable))

迭代器是可迭代对象的子类

所有异常都继承于BaseException

1.基本语法

class MyClass():
    a = 6

try:
    lst = [1,2,3]
    lst[1000]
except:
    pass
    

try:
    lst = [1,2,3]
    lst[1000]
except BaseException:
    pass

捕获异常,程序就可以按照我们设计的方向运行,当有异常时,执行except的代码块;没异常时,执行try的代码块

写代码时有时只是想让代码可以跳过某些错误,继续运行下去,会直接使用异常捕获,而不标明具体要捕获的错误是什么。此时会出现告警如上图,原因如下

这时pycharm就会提示:“Too broad exception claus”

直译过来就是:“例外的条款太广泛”

原因就是except之后没有标明具体的异常。

在Python里是,try后面使用except而不带任何异常类型,或者所接异常类太宽泛。这种使用方式是支持的,代码也可以正常运行。

只是except会捕获所有的错误,所以无法识别出具体的异常信息。

解决办法,指明具体异常类

2.带有分支的异常处理

try:
    # lst = [1,2,3]
    # lst[1000]
    
    # dic = {"a":1,"b":2}
    # dic["c"]
    
    # print(lisi)
    
    MyClass.abc()
except IndexError:
    print("下标越界1")
except KeyError:
    print("字典的键不存在2")
except NameError:
    print("这个变量不存在的3")
except :
    print("有异常错误4")

当有多个异常分支时,执行try中的代码,遇到异常,根据异常类型,执行相应except中的代码,后续代码不再执行

3.处理生成器的异常报错

def mygen():
    yield 1
    yield 2
    yield 3
    return [1,2,3]

try:
    gen = mygen()
    print(next(gen))
    print(next(gen))
    print(next(gen))
    print(next(gen))
    
    # 给StopIteration这个类创建出来的对象起一个别名叫e
    """ 
    当你打印对象时,会触发内部__str__方法,通过一些列的调用,返回出最后的返回值
    """
except StopIteration as e:
    # 可以获取返回值
    print(e)
    
    """
    # 额外的扩展
    res = str(e)
    print(res , type(res) ,  "<======>")
    res2 = eval(res)
    print(res2,type(res2))
    """

except StopIteration as e 是给StopIteration类创建个对象,起个别名为e,通过__str__方法,打印对象,就是打印返回值


也可以except异常父类:

BaseException有__str__方法,所以只要异常被捕获后有返回值,打印对象,返回值即被打印

4.异常处理的其他写法

1 .try … except … else …

当try这个代码块当中没有报错的时候,执行 try 和 else 分支

如果try代码块有报错,就不执行else这个分支,执行except分支

try:
    # lst = [1,2,3]
    # lst[1000]
    print(123)
except:
    pass
else:
    print("执行了else分支 ... ")

代码没报错,执行try和else里面的代码

代码有报错,执行try中报错之前的代码,和except中的代码,不执行else中的代码

2.try … finally … 无论代码是否报错,都必须要执行的代码写在finally这个代码块当中

场景:应用在异常环境下, 保存数据或者关闭数据库等操作, 必须要在数据库程序崩溃之前执行的代码写在finally代码块中;

try:
    lst = [1,2,3]
    lst[1000]
finally:    
    print(234678)

代码中有报错,还是执行了finally中的代码

3.try … except … else … finally …

try:
    lst = [1,2,3]
    lst[1000]
    # print(123)
    
except:
    print(456)
    
else:
    print("执行了else分支 ... ")
finally:
    print("执行关闭数据库操作")

代码中有报错,执行try报错之前的代码,except中的代码,finally中的代码

主动抛异常

有时候我们需要根据报错,得到错误的信息

可以在程序的指定位置手动抛出一个异常?答案是肯定的,Python 允许我们在程序中手动设置异常,使用 raise 语句即可。

读者可能会感到疑惑,即我们从来都是想方设法地让程序正常运行,为什么还要手动设置异常呢?

首先要分清楚程序发生异常和程序执行错误,它们完全是两码事,程序由于错误导致的运行异常,是需要程序员想办法解决的;

但还有一些异常,是程序正常运行的结果,比如用 raise 手动引发的异常

BaseException 所有异常类的父类

Exception 普通异常类的父类

raise + 异常错误类 / 异常错误类对象 一旦抛异常,则程序会中断,下面的代码不再执行

(1) raise 基本语法

raise KeyError
raise KeyError()  #括号中跟描述信息

raise抛出异常,后面必须接异常类型或异常对象,否则报错

主动抛出异常,程序报错。一般抛异常,就将特定的异常类型写清楚

try:
    raise 
except:
    pass

try:
    raise 
except BaseException:
    pass

(2) 自定义异常错误类

必须继承异常类的父类 BaseException

# return_errorinfo必须在报错的情况下才能触发内部相应方法获取当前行号和文件名
def return_errorinfo(n):
    import sys
    f = sys.exc_info()[2].tb_frame.f_back
    if n == 1:        
        return str(f.f_lineno)      #返回当前行数
    elif n == 2:    
        return f.f_code.co_filename #返回文件名    


# 通过主动抛出异常,来获取响应的数据
def get_info(n):
    try:
        raise 
    except:
        return return_errorinfo(n)

# 自定义异常错误类
class MyException(BaseException):
    def __init__(self,error_num,error_msg,error_filename,error_linenum):
        self.error_num = error_num
        self.error_msg = error_msg
        self.error_filename = error_filename
        self.error_linenum = error_linenum

eye = "轮回眼"
try:
    if eye == "轮回眼":
        raise MyException( 404,"人类没有轮回眼",get_info(2) , get_info(1) )         
        
except MyException as e: # 给自定义MyException异常类的对象起个别名叫做e
    print(e.error_num)
    print(e.error_msg)
    print(e.error_filename)
    print(e.error_linenum)


相关文章
|
2月前
|
安全 Linux 网络安全
Kali 渗透测试:基于结构化异常处理的渗透-使用Python编写渗透模块(一)
Kali 渗透测试:基于结构化异常处理的渗透-使用Python编写渗透模块(一)
66 2
|
2月前
|
Python Windows 网络安全
Kali 渗透测试:基于结构化异常处理的渗透-使用Python编写渗透模块(二)
Kali 渗透测试:基于结构化异常处理的渗透-使用Python编写渗透模块(二)
68 2
|
4月前
|
数据库连接 Python
Python中的异常处理除了Try语句,你还会啥?
Python中的异常处理除了Try语句,你还会啥?
67 1
|
4月前
|
Python
|
3月前
|
Python
Python编程中的异常处理:理解与实践
【9月更文挑战第14天】在编码的世界里,错误是不可避免的。它们就像路上的绊脚石,让我们的程序跌跌撞撞。但是,如果我们能够预见并优雅地处理这些错误,我们的程序就能像芭蕾舞者一样,即使在跌倒的边缘,也能轻盈地起舞。本文将带你深入了解Python中的异常处理机制,让你的代码在面对意外时,依然能保持优雅和从容。
160 73
|
2月前
|
安全 Java 程序员
Python 异常处理!
本文详细介绍了Python中的异常处理,包括try、except和finally语句的使用方法。文章区分了语法错误与异常,并列举了Python中常见的异常类型,如`SyntaxError`、`TypeError`等。通过具体示例展示了如何使用try-except块捕获和处理异常,以及如何结合else和finally子句增强代码的健壮性和可读性。此外,还介绍了如何使用raise语句主动抛出异常。通过合理的异常处理,可以提高程序的可靠性与调试效率,但也可能带来性能开销和代码复杂度的增加。
42 4
|
2月前
|
IDE 开发工具 开发者
Python中的异常处理与调试技巧
【9月更文挑战第32天】在软件开发中,错误和异常是难以避免的。了解如何有效处理这些情况对于编写健壮、可靠的代码至关重要。本文将深入探讨Python中的异常处理机制,介绍如何使用try-except语句捕捉异常,以及如何利用Python的调试工具来诊断问题。通过实际示例,我们将展示如何优雅地处理异常并提高代码质量。
|
3月前
|
对象存储 索引 Python
30天拿下Python之异常处理
30天拿下Python之异常处理
35 3
|
2月前
|
安全 数据库连接 开发者
深度解析Python上下文管理器:优雅资源管理与异常处理
深度解析Python上下文管理器:优雅资源管理与异常处理
25 0
|
4月前
|
IDE 测试技术 开发工具
Python接口自动化测试框架(基础篇)-- 讨厌的异常处理
本文详细讨论了Python中的异常处理机制,包括异常捕获、异常抛出、自定义异常、环境清理,以及使用上下文管理器确保资源正确释放,最后还提到了Python的标准异常类。
37 1