Python学习08——错误与异常


哈喽,我们又见面啦~
到目前位置,我们见过许多错误信息,但我们只是对它有一个较为浅显的认识。在这一节中,我们将好好学习错误与异常,以及了解应该怎么去处理。

错误与异常

语法错误

语法错误又称解析错误,可能是我们学习Python中最容易遇到的错误了。例如,当我们编写如下代码时:

"""
语法错误
"""
if a<5
    print(a)

运行程序后,我们得到下图的错误提示。原因是我们在编写if语句时,忘记在判断条件后添加:,不符合python语法规范,因此解释器提示”SyntaxError“。
在这里插入图片描述

异常

即使语句或表达式在语法上是正确的,但在尝试执行的时候,程序仍有可能出现错误。在执行时检测到的错误被称为异常。还记得我们当初讲字符串时的索引越界吗?

"""
索引越界
"""
message="Hello world"

#得到字符串长度
mes_len=len(message)
print(mes_len)    #11

#别忘是索引是从0开始的。
#虽然字符串的长度为mes_len,但可用的索引最大值为 (mes_len-1)
#故mes_len索引越界
print(message[mes_len])

在这段代码中,语句和表达式在语法上都是正确的,但当我们执行程序的时候,会显示出如下所示的异常信息。
在这里插入图片描述
错误信息的前一部分以堆栈的形式显示发生异常的上下文。通常它会列出发生错误的源代码的堆栈回溯(简单理解,就是一层一层地拨开,先是最表层的发生异常的代码的信息;若有进行函数调用,就继续返回函数调用内部的异常信息;直到找到最根源的异常为止)。

"""
堆栈回溯示例
"""
def div_zero(a):
    """将输入的值除以0"""
    return a/0

def call_div_zero(a):
    """"调用div_zero()"""
    return div_zero(a)

#调用call_div_zero()
call_div_zero(4)

在这里插入图片描述

异常处理

try…except…

try语句的工作原理如下:

  • 首先,执行try子句(try和except之间的语句)
  • 若没有发生异常,则跳过except子句
  • 若发生了异常,则跳过过该子句的剩下部分,跳转到except子句。若异常的类型和except后接的异常匹配,则执行对应的except子句,执行完后再跳转回未执行完的try子句中的代码段
  • 若发生的异常和 except 子句中指定的异常不匹配,则将其传递到外部的 try 语句中。
"""
try...except...示例
"""

def get_number():
    """
    输入被除数和除数
    若产生数据类型转换错误,则处理
    """
    while True:
        a=input("input the first number: ")
        b=input("input the second number: ")
        try:
            num1=int(a)
            num2=int(b)
            break
        except ValueError:
            print("please input numbers,try it again!\n")
    return num1,num2

def div():
    """
    进行除法操作
    若产生除零异常,则处理
    """
    while True:
        try:
            num1,num2=get_number()
            result=num1/num2
            print(f"the answer is {result}")
            break
        except ZeroDivisionError:
            print("you can not divide by zero, try it again!\n")
div()

在这里插入图片描述

try…except…else…

同if语句相似,一个 try 语句可能有多个 except 子句,以指定不同异常的处理程序。
try … except 语句还有一个可选的 else 子句,在使用时必须放在所有的 except 子句后面。对于在try 子句不引发异常时必须执行的代码来说很有用。使用 else 子句比向 try 子句添加额外的代码要好,因为它避免了意外捕获由 try … except 语句保护的代码未引发的异常。

import sys

for arg in sys.argv[:]:
    try:
        f = open(arg, 'r')
    except OSError:
        print('cannot open', arg)
    else:
        print(arg, 'has', len(f.readlines()), 'lines')
        f.close()

try…except…finally…

finally子句是try 语句中另一个可选子句,用于定义必须在所有情况下执行的清理操作。
如果存在 finally 子句,则 finally 子句将作为 try 语句结束前的最后一项任务被执行。 finally 子句不论 try 语句是否产生了异常都会被执行。 以下几点讨论了当异常发生时一些更复杂的情况:

  • 如果在执行 try 子句期间发生了异常,该异常可由一个 except 子句进行处理。 如果异常没有被某个 except 子句所处理,则该异常会在 finally 子句执行之后被重新引发。
  • 异常也可能在 except 或 else 子句执行期间发生。 同样地,该异常会在 finally 子句执行之后被重新引发。
  • 如果在执行 try 语句时遇到一个 break, continue 或 return 语句,则 finally 子句将在执行 break, continue 或 return 语句之前被执行。
  • 如果 finally 子句中包含一个 return 语句,则返回值将来自 finally 子句的某个 return 语句的返回值,而非来自 try 子句的 return 语句的返回值。
"""
如果 finally 子句中包含一个 return 语句
则返回值将来自 finally 子句的某个 return 语句的返回值
而非来自 try 子句的 return 语句的返回值。
"""

def bool_return():
    try:
        return True
    finally:
        return False

print(bool_return())

更复杂的情况

"""
finall更复杂的情况
"""

while True:
   try:
       x=input("input the first number: ")
       y=input("input the second number: ")
       result = int(x) / int(y)
   except ZeroDivisionError:
       print("division by zero!")
   else:
       print("result is", result)
   finally:
       print("executing finally clause\n")

在这里插入图片描述

raise

raise 语句允许程序员强制发生指定的异常。例如:

try:
    raise NameError('HiThere')      #抛出一个NameError异常
except NameError:
    print('An exception flew by!')

小结

兜兜转转,也写了这么几天的博客了。也不知道屏幕前的你,是否有从中得到什么,无论好或不好,希望你能告诉我。
今天就这样吧,晚安!

附表

Python 标准异常总结

异常名描述
BaseException所有异常的 基类
Exception常规异常的 基类
StandardError所有的内建标准异常的基类
ArithmeticError所有数值计算异常的基类
FloatingPointError浮点计算异常
OverflowError数值运算超出最大限制
ZeroDivisionError除数为零
AssertionError断言语句(assert)失败
AttributeError尝试访问未知的对象属性
EOFError没有内建输入,到达EOF标记
EnvironmentError操作系统异常的基类
IOError输入/输出操作失败
OSError操作系统产生的异常(例如打开一个不存在的文件)
WindowsError系统调用失败
ImportError导入模块失败的时候
KeyboardInterrupt用户中断执行
LookupError无效数据查询的基类
IndexError索引超出序列的范围
KeyError字典中查找一个不存在的关键字
MemoryError内存溢出(可通过删除对象释放内存)
NameError尝试访问一个不存在的变量
UnboundLocalError访问未初始化的本地变量
ReferenceError弱引用试图访问已经垃圾回收了的对象
RuntimeError一般的运行时异常
NotImplementedError尚未实现的方法
SyntaxError语法错误导致的异常
IndentationError缩进错误导致的异常
TabErrorTab和空格混用
SystemError一般的解释器系统异常
TypeError不同类型间的无效操作
ValueError传入无效的参数
UnicodeErrorUnicode相关的异常
UnicodeDecodeErrorUnicode解码时的异常
UnicodeEncodeErrorUnicode编码错误导致的异常
UnicodeTranslateErrorUnicode转换错误导致的异常

异常体系内部有层次关系,Python异常体系中的部分关系如下所示:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值