- 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 )
异常类型捕获演练–要求用户输入整数
需求
- 提示用户输入一个整数
- 使用 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
无论是否出现异常,都会运行
----------
七、异常的传递
- 异常的传递 – 当 函数/方法 执行 出现异常 ,会 将异常传递 给函数/方法 的调用一方
- 如果 传递到主程序 ,任然没有 异常处理 ,程序才会被终止
- 提示
- 再开发中,可以再主函数中增加 异常捕获
- 而再主函数中调用的其他函数,只要出现异常,就会传递到主函数的 异常捕获 中
- 这样就不需要再大妈中,增加大量的的 异常捕获 ,能够保证代码的整洁
需求
- 定义函数
demo1()
提示用户输入一个整数并返回 - 定义函数
demo2()
调用demo1
- 在主程序中调用
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
异常类 -
在开发时,如果满足 特定业务需求时,希望 抛出异常, 可以:
- 创建一个
Exception
的对象 - 使用
raise
关键字 抛出 异常对象
需求
- 定义
input_password
函数,提示用户输入密码 - 如果用户输入长度<8,抛出异常
- 如果用户输入长度>=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
主动抛出异常
密码长度不够