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)


相关文章
|
1月前
|
程序员 开发者 Python
Python网络编程基础(Socket编程) 错误处理和异常处理的最佳实践
【4月更文挑战第11天】在网络编程中,错误处理和异常管理不仅是为了程序的健壮性,也是为了提供清晰的用户反馈以及优雅的故障恢复。在前面的章节中,我们讨论了如何使用`try-except`语句来处理网络错误。现在,我们将深入探讨错误处理和异常处理的最佳实践。
|
1月前
|
Python
python基础篇:如何把异常处理做的更加优雅
python基础篇:如何把异常处理做的更加优雅
20 2
|
1月前
|
安全 程序员 Python
Python中的异常处理与错误调试
【4月更文挑战第8天】本文探讨Python中的异常处理和错误调试,将其比喻为驾驶过程中的意外情况。异常是程序执行时的非正常事件,如文件缺失或网络故障,而错误是代码本身的逻辑或语法问题。Python通过try-except语句处理异常,确保程序在遇到问题时不会立即崩溃。错误调试则需定位问题根源,利用pdb等工具逐行检查代码。这两个技能对保持代码稳定性和可靠性至关重要,能增强程序应对意外的能力并帮助修复潜在问题。
|
1月前
|
索引 Python
python异常处理
python异常处理
|
4天前
|
开发者 Python
【Python 基础】Python中的异常处理是如何进行的?
【5月更文挑战第8天】【Python 基础】Python中的异常处理是如何进行的?
|
5天前
|
Python
Python 中的异常处理机制是一种强大的错误处理工具
Python的异常处理机制借助try/except结构管理错误,提高程序健壮性。异常是中断正常流程的问题,可由多种原因引发。基本结构包括try块(执行可能出错的代码)和except块(处理异常)。通过多个except块可捕获不同类型的异常,finally块确保无论是否异常都执行的代码。此外,raise语句用于主动抛出异常,自定义异常通过继承Exception类实现。with语句配合上下文管理器简化资源管理并确保异常情况下资源正确释放。
17 2
|
6天前
|
程序员 开发者 Python
Python中的异常处理技巧与最佳实践
异常处理在Python编程中至关重要,它能够有效地帮助开发人员识别和解决程序中的错误。本文将介绍Python中常见的异常类型,探讨异常处理的最佳实践,并提供一些实用的技巧,帮助开发者编写更健壮的代码。
|
12天前
|
存储 测试技术 数据库连接
Python异常处理
【5月更文挑战第1天】在Python编程中,异常处理是构建健壮代码的关键。本文介绍了异常处理基础,包括`try`、`except`、`finally`和`raise`关键字的使用。通过示例展示了如何捕获和处理`ZeroDivisionError`等特定异常,以及如何利用`finally`确保资源清理。此外,还分享了最佳实践,如明确指定异常类型、避免捕获所有异常、使用`finally`进行资源清理和记录异常信息。
16 6
|
15天前
|
Python
探索Python中的异常处理机制
异常处理是Python编程中至关重要的一环。本文将深入探讨Python中的异常处理机制,包括异常的基本概念、常见的内置异常类型以及如何使用try-except语句来捕获和处理异常。通过详细的示例和解释,读者将对Python中的异常处理有一个全面的了解,并能够编写更加健壮和可靠的代码。
|
19天前
|
运维 Shell Python
第七章 Python异常处理
第七章 Python异常处理