异常处理

Posted wanlei

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了异常处理相关的知识,希望对你有一定的参考价值。

一、什么是异常

异常是错误发生前的一种信号,如果没有人来处理这个信, 程序就会中断执行并抛出错误信息。

二、异常的分类

1.语法检查异常
2.运行时异常(逻辑异常)
这种异常只有在代码被执行时才能发现

特点:在没有运行代码前 是无法发现的
如果运行时异常已经发生并且没有正确处理他 就抛出错误信息
并且中断程序的执行。

三、异常的组成

1.追踪信息 (具体发生异常的位置 以及函数的调用顺序)
2.异常的类型 (错误的类型)
3.异常的消息 (详细的错误信息)

学习异常处理的目的:为了让我们的程序更加稳定 (健壮性) 不容易崩溃

 

name =
def func():
    import xxaaa

def func1():
    func()

func1()
  File "C:/Users/xxx/PycharmProjects/MyFirstPro/chapter5-面向对象//异常处理.py", line 32
    name =
         ^
SyntaxError: invalid syntax

四、常见的异常

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

五、异常处理

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

常用基本语法:

    try:
        这里放可能出现异常的代码
    except: 异常的类型:
        当异常发生并且异常类型匹配时
        执行except中的代码
    注意:一旦try中有代码抛出了异常 后面的代码全都不执行

# print("staring.....")
# try:
#     name
# except NameError:
#     print("名字找不到!")
# print("end.......")
#多种异常类型处理
# print("staring.....")
# try:
#     name
#     [][-1]
#     pass
# except NameError:
#     print("名字找不到!")
# except IndexError:
#     print("索引超出范围")
# print("end.......")

当代码可能出现多种异常时的写法时:(两种写法)

 

# print("staring.....")
# try:
#     # name
#     # [][-1]
#     1/0
#     pass
# except NameError:
#     print("名字找不到!")
# except IndexError:
#     print("索引超出范围")
# except ZeroDivisionError:
#     print("除数不能为0")
# print("end.......")

 

 

 

# print("staring.....")
# try:
#     {}["aaa"]
#     # name
#     # [][-1]
#     1/0
# except (NameError,IndexError,ZeroDivisionError):
#     print("可能名字找不到! 可能所以超出范围 可能除数为0")
# print("end.......")

# 上面两种写法 都可以处理多种异常 但是 异常类型太多了 不可能全写完

注意:万能异常类型 Exception 或BaseException   基于OOP的继承和多态

再例举几种不太常用的语法:

语法1
  try:
  except:
  else: try中没有发生异常时执行

语法2
  try :
  except :
  finally : 无论是否发生异常 都会执行finally  可以用来回收系统资源!
# print("start...")
# try:
#     # 1/0
#     [][1]
#     pass
# except ZeroDivisionError:
#     print("除数异常")
# except NameError:
#     print("名字异常")
# else:
#     print("else会在 try中没有异常时执行")
# print("end...")
 finally
# print("start...")
# try:
#     # 1/0
#     # [][1]
#     pass
# except ZeroDivisionError:
#     print("除数异常")
# except IndexError:
#     print("索引异常")
# else:
#     print("else会在 try中没有异常时执行")
# finally:
#     print("finally 无论异常是否发生 都会执行!")
# print("end...")
# 使用finally来回收资源
try:
    f = open(r"D:上海python全栈4期day31异常处理1今日内容","rt",encoding="utf-8")
    f.read()
    # f.write("123")
except Exception:
    print("发生异常了")
finally:
    print("关闭文件!")
    f.close()
print(f.closed)

主动抛出异常:

"""
    当程序中有一些限制 然而用户没有遵守 我们可以主动抛出异常
    语法:
        raise 异常类型(异常的详细信息)
        类型必须是BaseException的子类
"""
# raise NameError("这就是名字不存在异常!")

age = input("请输入整型的年龄:")
if not age.isdigit():
    raise TypeError("你输入的不是整型!")
age = int(age)
print("十年后你%s岁" % (age + 10))

断言:(断定 就是很清楚 很明确)

啥时候用? 下面的代码必须依赖上面代码的正确数据
语法: assert 结果为Bool的表达式
如果值为True 则继续往下执行
为False 抛出一个 AssertionError 表示断言失败
没有assert 也可以使用if,assert 仅仅是简化了代码

# 第一部分代码 负责产生一个列表
li = []
# li.append(1)
# li.append(2)
# 这里一定要确保数据是有效的
# if len(li) < 1:
#     raise ValueError("列表中没有数据!")
assert len(li) > 0
# 需要使用列表中的数据来完成任务 如果没有数据无法完成
print(li[0])
print(li[0])
print(li[0])
print(li[0])

自定义异常类型

当系统提供的这些异常类型 和你要描述的错误不匹配时 就需要自定义异常类型

写法:
class 自定义异常类型名称(BaseException):
总结一下:之所以自定义异常类型 是为了更具体描述你的错误 让使用者一眼就看出了

关键点:

1.如何自定义异常类型
2.在except中 使用as 来获取异常对象

class UnlikeError(BaseException):
    def __init__(self,msg,text):
        self.msg = msg
        self.text = text
# 函数中可能抛出异常
def hello():
    text = input("输入一段话:")
    if text == "你真帅":
        print("你说得对!")
    else:
        raise UnlikeError("你再看看...","另一个参数")
# 捕获异常
try:
    hello()
# 获取异常对象
except UnlikeError as e:
    print(e.text)

conclusion:

不应该滥用try except
什么时候用? 如果你知道为什么出错 应该把代码修改正确 而不是加上try except,寻找代码根本错误问题是关键!
你不清楚为什么会发生异常! 这时候可以用。

try:
    f = open("xxxx","rt")
    f.read()
except Exception:
    print("文件不存在!")

 




















以上是关于异常处理的主要内容,如果未能解决你的问题,请参考以下文章

使用片段中的处理程序时出现非法状态异常

Java异常处理机制

java 反射代码片段

java.util.MissingResourceException: Can't find bundle for base name init, locale zh_CN问题的处理(代码片段

使用实体框架迁移时 SQL Server 连接抛出异常 - 添加代码片段

片段中的Android致命异常