异常处理

 一.异常是什么

什么是异常?

  异常就是错误发生前的一种信号

  如果没有人来处理这个异常 程序就会中断执行并抛出错误信息

异常的分类:

  1.语法检查异常 这种异常时最低级异常 绝不应该犯(犯了就可能卷铺盖走人了)

    也非常好避免

    如果是编译器 会自动提示

    如果是文本编辑器 在你运行代码前 解释器会检查语法

  2.运行时异常(逻辑异常)

    这种异常只有在代码被执行时才能发现

    我们要处理的重点就是运行时异常

    特点:在没有运行代码前 是无法发现的

      如果运行异常已经发生并且没有正确处理他,就抛出错误信息

      并且中断程序的执行 这是要我们学校异常解决的问题

异常的组成

  1.追踪信息(具体发生异常的位置 以及函数的调用顺序)

  2.异常的类型(错误的类型)

  3.异常的消息(详细的错误信息)

我们之所以学习异常处理

  为的是让我们的程序更加稳定(健壮性)不容易崩溃

name=

def func():

  import xxaaa

def func1():

  func()

func1()

二.常见异常

常见异常及发生原因:

  NameError 找不到这个名字 要么变量 要么函数

  ValueError 在调用一个函数时给的值不正确

  TypeError类型错误 例如字符串与数字加减乘除 调用一个不能被调用的类型

  ZeroDivisionError 除数不能为0

  KeyError 没有这个key

  IndexError 索引不存在

  StopIteration 没有更多的值可以迭代

  FileNotFoundError 文件不存在

  io.UnsupportedOperation 文件的操作不支持

  AttributeError 没有这个属性

  KeyboardInterrupt 程序被强行终止 ctrl+c

三 异常处理

要处理异常

  要学的就是一个新的语法

  今后使用最多的写法:

  try:

    这里放可能出现异常的代码

  except:异常的类型

    当异常发生并且异常类型匹配时

    执行except中的代码

  注意:一旦try中有代码抛出了异常 后面的代码全都不执行

  练习:捕获某种类型的异常 捕获任意类异常 感受一下执行顺序

基本语法

print("starting....")

try:

  name

except NameErrop:

  ptint("名字找不到")

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:

  #name

  #[][-1]

  1/0

  pass

except NameError:

  print("名字找不到!")

except IndexError:

  print("索引超出范围")

except ZeroDivisionError:

  print("end.......")

 

当代码可能出现多种异常时的写法2
print("staring.....")
try:
  {}["aaa"]
  #name
   [][-1]
  1/0
except (NameError,IndexError,ZeroDivisionError):
  print("可能名字找不到! 可能所以超出范围 可能除数为0")
print("end.......")

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

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

print("staring.....")

try:

  #{}["aaa]

  #name

  #1/0

except Exception:

  print("可能名字找不到!可能所以超出范围 可能除数为0")

print("end.......") 

 

五.不太常用的语法

语法1

try:

except:

else: try中没有发生异常时执行

 

语法2

try:

except:

finally:无论是否发生异常 都会执行finally 可以用来回收系统资源!

 

print("start...")

try:

  #1/0

  [][1]

  pass

except ZeroDivisionError:

  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.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.apppend(2)

这里一定要确保数据有效的

if len(li)<1:

  raise ValueError("列表中没有数据")

assert len(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)

九.使用场景

try:
  print("业务逻辑分层复杂 写了好几百行!")
except Exception:
  print("可能是文件不存在!")
try:
  print("业务逻辑分层复杂 写了好几百行!")
except Exception:
  print("类型不匹配!")
  print("业务逻辑分层复杂 写了好几百行!")
  print("业务逻辑分层复杂 写了好几百行!")
  print("业务逻辑分层复杂 写了好几百行!")
  print("业务逻辑分层复杂 写了好几百行!")
  print("业务逻辑分层复杂 写了好几百行!")
  print("业务逻辑分层复杂 写了好几百行!")
  print("业务逻辑分层复杂 写了好几百行!")
  print("业务逻辑分层复杂 写了好几百行!")
  print("业务逻辑分层复杂 写了好几百行!")
  print("业务逻辑分层复杂 写了好几百行!")
  print("业务逻辑分层复杂 写了好几百行!")
  print("业务逻辑分层复杂 写了好几百行!")
except Exception:
  print("有点问题!")


# 不应该滥用try except
# 什么时候用? 如果你知道为什么出错 应该把代码修改正确 而不是加上try except
# 你不清楚为什么会发生异常! 这时候用try

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

 

posted @ 2018-11-01 17:29  Milford  阅读(221)  评论(0编辑  收藏  举报