【程序异常】—python[try,raise,error]

  • def:python程序一般对输入有一定的要求,当实际输入不满足程序要求时,可能回产生程序的运行错误。
  • def:程序在运行时,如果python解释器遇到一个错误,会停止程序的执行,并且提示一些错误信息,这就是异常
  • def:程序停止执行并且提示错误信息这个动作,我们通常称之为:抛出(raise)异常

一、输入异常

n=eval(input("请输入一个数字: "))

eval函数就是实现list、dict、tuple与str之间的转换。

eval(‘列表’)将字符串转换为列表

eval(‘字典’)将字符串转换为字典

eval(‘元组’)将字符串转换为元组

》》请输入一个整数:python

》错误为

NameError                                 Traceback (most recent call last)
<ipython-input-1-bf06375c482c> in <module>
----> 1 n=eval(input("请输入一个数字: "))

<string> in <module>

NameError: name 'python' is not defined

由于使用了eval()函数,如果用户输入不是一个数字则可能报错。这类由于输入与预期不匹配造成的错误有很多种可能,不能逐一列出可能性进行判断。为了保证程序运行的稳定性,这类运行错误应该被程序捕获并合理控制

  • python 语言使用保留字 try 和 except 进行异常处理,基本语法格式如下:

    try:

    ​ <语句块1>

    except:

    ​ <语句块2>

  • 语句块1是正常执行的程序内容,当执行这个语句块发生异常时,则执行except保留字后面的语句块2

try:
    n=eval(input("请输入一个数字: "))
    print("输入数字的3次方值为:",n**3)
except:
    print("输入错误,请输入一个数字!")

输入–结果

请输入一个数字: 101
输入数字的3次方值为: 1030301

请输入一个数字: python
输入错误,请输入一个数字

二、程序执行异常

for i in range(5):
    print(10/i,end=' ')

》错误为:

ZeroDivisionError                         Traceback (most recent call last)
<ipython-input-5-8794c0c942e3> in <module>
      1 for i in range(5):
----> 2     print(10/i,end=' ')

ZeroDivisionError: division by zer
  • 保留字 try 和 except 进行异常处理
try:
    for i in range(5):
        print(10/i,end=' ')
except:
    print("因为某种原因出错了")

结果—输出

因为某种原因出错了
  • 使用try 和 except 以及更进一步判断异常
try:
    for i in range(5):
        print(10/i,end=' ')
except ZeroDivisionError:
    print("除数为0,产生错误了")    
except:
    print("因为某种原因出错了")

结果—输出

除数为0,产生错误了

程序开发时,很难将*所有的特殊情况都处理的面面俱到,通过异常捕获可以针对突发事件做集中的处理,从而保证程序的稳定性和健壮性

三、捕获异常

  • 在程序开发中,如果对某些代码的执行不能确定是否正确.可以增加try(尝试)lai捕获异常
  • 捕获异常的最简单的语法格式:
try:
    尝试执行的代码
except:
    出现错误的处理
  • try尝试,下方编写要尝试的代码,不确定是否能够正常执行的代码
  • except如果不是,下方编写尝试失败的代码

简单异常捕获演练—要求用户输入整数

#提示用户输入一个数字
num=int(input("请输入数字: "))

》》输入:a

》错误为:

ValueError                                Traceback (most recent call last)
<ipython-input-12-46a7771df1a5> in <module>
----> 1 num=int(input("请输入数字: "))

ValueError: invalid literal for int() with base 10: 'a' 

int()化为10进制的整数

(自己的理解)捕获错误的目的:是使程序能够继续运行下去,并对突发事件集中处理

四、根据错误类型捕获异常

  • 在程序执行时,可能会遇到不同类型的异常,并且需要 针对不同类型的异常,做出不同的响应,这个时候,就需要捕获错误类型了
  • 语法如下:
try:
    #尝试执行的代码
exvept 错误类型1# 针对错误类型1 ,对应的代码处理
    pass
except (错误类型2,错误类型3):
    # 针对错误类型2 和 3 ,对应的代码处理
    pass
except Exveption as result:
    print("未知错误 %s " % result )

异常类型捕获演练–要求用户输入整数

需求

  1. 提示用户输入一个整数
  2. 使用 8 初一用书输入的整数并且输出
#提示用户输入一个数字
num=int(input("请输入数字: "))

#使用 8 初一用书输入的整数并且输出
result=8/ num

print(result)

输入不同,会导致不同的错误类型

》》请输入数字:a

》错误为:

ValueError                                Traceback (most recent call last)
<ipython-input-1-ec985d930497> in <module>
      1 #提示用户输入一个数字
----> 2 num=int(input("请输入数字: "))
      3 
      4 #使用 8 初一用书输入的整数并且输出
      5 result=8/ num

ValueError: invalid literal for int() with base 10: 'a

》》请输入数字:0

》错误为:

ZeroDivisionError                         Traceback (most recent call last)
<ipython-input-2-ec985d930497> in <module>
      3 
      4 #使用 8 初一用书输入的整数并且输出
----> 5 result=8/ num
      6 
      7 print(result)

ZeroDivisionError: division by zero

那么,我们需要根据不同的错误类型,做出不同的处理,此时错误类型如何获取呢?

  • pyhton解释器抛出异常时,最后一行错误的第一个单词,就是错误类型
try:
    #提示用户输入一个数字
    num=int(input("请输入数字: "))

    #使用 8 初一用书输入的整数并且输出
    result=8/ num

    print(result)
except ZeroDivisionError:
    print("除0错误")
except ValueError:
    print("请输入正确的整数!")

》》输入-结果

请输入数字: 0
除0错误
请输入数字: a
请输入正确的整数!

五、捕获未知错误

  • 在开发时,要预判所有可能出现的错误,还是有一定的难度的
  • 如果希望程序 无论出现任何错误,都不会因为python解释器** 抛出异常而被终止**,可以再增加一个except
  • 语法如下:
except Exveption as result:
    print("未知错误 %s" % result)

#result 这个变量名可以随便写

案例

try:
    #提示用户输入一个数字
    num=int(input("请输入数字: "))

    #使用 8 初一用书输入的整数并且输出
    result=8/ num

    print(result)
except ZeroDivisionError:
    print("除0错误")
except Exception as result:
    print("未知错误 %s" % result)

》》输入–结果

请输入数字: a
未知错误 invalid literal for int() with base 10: 'a'

六、异常捕获王正的语法

再实际剋发中,为了能够处理复杂的异常情况,完整的异常语法如下:

try:
    #尝试执行的代码
exvept 错误类型1# 针对错误类型1 ,对应的代码处理
    pass
except (错误类型2,错误类型3):
    # 针对错误类型2 和 3 ,对应的代码处理
    pass
except Exveption as result:
    print("未知错误 %s " % result )
else:
    # 没有异常才会执行的代码
    pass
finally:
    #无论是否有异常,都会执行的代码
    print(“无论是否有异常,都会执行的代码”)  

else只有再没有异常时才会执行的代码

finally无论是否有异常,都会执行的代码

案例

try:
    #提示用户输入一个数字
    num=int(input("请输入数字: "))

    #使用 8 初一用书输入的整数并且输出
    result=8/ num

    print(result)
except ValueError:
    print("除0错误")
except Exception as result:
    print("未知错误 %s" % result)
else:
    print("尝试成功")
finally:
    print("无论是否出现异常,都会运行")
print("-"*10)

》》输入–结果

请输入数字: 8
1.0
尝试成功
无论是否出现异常,都会运行
----------
请输入数字: 0
未知错误 division by zero
无论是否出现异常,都会运行
----------

七、异常的传递

  • 异常的传递 – 函数/方法 执行 出现异常 ,会 将异常传递 给函数/方法 的调用一方
  • 如果 传递到主程序 ,任然没有 异常处理 ,程序才会被终止
  • 提示
  • 再开发中,可以再主函数中增加 异常捕获
  • 而再主函数中调用的其他函数,只要出现异常,就会传递到主函数的 异常捕获
  • 这样就不需要再大妈中,增加大量的的 异常捕获 ,能够保证代码的整洁

需求

  1. 定义函数demo1() 提示用户输入一个整数并返回
  2. 定义函数demo2() 调用demo1
  3. 在主程序中调用demo2()
def demo1():
    return int(input("输入整数: "))
    
    
print(demo1())

输入整数:a

ValueError                                Traceback (most recent call last)
<ipython-input-14-90caedb68224> in <module>
      3 
      4 
----> 5 print(demo1())

<ipython-input-14-90caedb68224> in demo1()
      1 def demo1():
----> 2     return int(input("输入整数: "))
      3 
      4 
      5 print(demo1())

ValueError: invalid literal for int() with base 10: 'a

错误的类型为ValueError,真正出错的位置是第2行,但将错误传递到主函数中(也就是第5行),在主函数中没有找到解决错误异常的方法,才执行报错

扩展

def demo1():
    return int(input("输入整数: "))
def demo2():
    return demo1()
print(demo2())

输入整数:a

ValueError                                Traceback (most recent call last)
<ipython-input-15-8ab45ad5093e> in <module>
      3 def demo2():
      4     return demo1()
----> 5 print(demo2())

<ipython-input-15-8ab45ad5093e> in demo2()
      2     return int(input("输入整数: "))
      3 def demo2():
----> 4     return demo1()
      5 print(demo2())

<ipython-input-15-8ab45ad5093e> in demo1()
      1 def demo1():
----> 2     return int(input("输入整数: "))
      3 def demo2():
      4     return demo1()
      5 print(demo2())

ValueError: invalid literal for int() with base 10: 'a
  • 错误类型为ValueError,真正出错的为第2行,
  • 然后传递到第4行,没有找到异常处理
  • 然后传递到主函数,即第5行,没有找到异常处理,然后报错

如果我们在每个函数中都写try语句,会非常繁琐,那怎么简化呢

我们利用异常的传递性,在主程序中捕获异常

def demo1():
    return int(input("输入整数: "))
def demo2():
    return demo1()
try:
    print(demo2())
except Exception as result:
    print("未知错误 %s" %result)

》输入–结果

输入整数: a
未知错误 invalid literal for int() with base 10: 'a'

八、主动 抛出(raise) 异常

8.1 应用场景

  • 在开发中,除了 代码执行出错python解释器会 抛出 异常外
  • 还可以根据 应用程序 特征的业务需求 主动抛出异常
  • 示例

提示用户 输入密码 ,如果 长度少于8, 抛出 异常


用书输入的密码
密码长度不够抛出异常
输入密码函数
用户登录模块

注意:

  • 当前函数 只负责 提示用户输入密码,如果 密码长度不争取,需要其他的函数进行额外处理
  • 因此可以 抛出异常 ,由其他需要处理的函数 **捕获异常

8.2 抛出异常

  • python中提供了一个Exception异常类

  • 在开发时,如果满足 特定业务需求时,希望 抛出异常, 可以:

    1. 创建一个Exception的对象
    2. 使用raise关键字 抛出 异常对象

    需求

    1. 定义input_password函数,提示用户输入密码
    2. 如果用户输入长度<8,抛出异常
    3. 如果用户输入长度>=8,返回输入的密码
def input_password():
    #1.提示用户输入密码
    pwd=input("请输入密码: ")
     #2.判断密码长度>=8,返回用户输入的密码
    if len(pwd)>=8:
        return pwd
     #3.如果<8,主动抛出异常
    print("主动抛出异常")
     #1>创建异常对象,可以使用错误信息字符串作为参数
    ex=Exception("密码长度不够")
     #2> 主动抛出异常
    raise ex
    
input_password()

》》输入–结果

请输入密码: 12345678

Out[20]:

'12345678'

》》输入–结果

请输入密码: a
主动抛出异常
---------------------------------------------------------------------------
Exception                                 Traceback (most recent call last)
<ipython-input-21-ecc20be9782b> in <module>
     12     raise ex
     13 
---> 14 input_password()

<ipython-input-21-ecc20be9782b> in input_password()
     10     ex=Exception("密码长度不够")
     11      #2> 主动抛出异常
---> 12     raise ex
     13 
     14 input_password()

Exception: 密码长度不够
  • 可以看最后一行,为异常的名称“密码长度不够”(自己创建的异常),

  • 异常的初始位置在第12行

  • 然后传递给第14行

接下来,对于抛出的异常,我们尝试捕获

def input_password():
    #1.提示用户输入密码
    pwd=input("请输入密码: ")
     #2.判断密码长度>=8,返回用户输入的密码
    if len(pwd)>=8:
        return pwd
     #3.如果<8,主动抛出异常
    print("主动抛出异常")
     #1>创建异常对象
    ex=Exception("密码长度不够")
     #2> 主动抛出异常
    raise ex
try:    
    input_password()
except Exception as result:
    print(result)

》》输入–结果

请输入密码: a
主动抛出异常
密码长度不够
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值