一、错误与异常
1.1 语法错误
print('helllo' #缺少右括号 )
a = 1
if a #缺少冒号 :
print('ok')
def test: #缺少圆括号 ()
print("sdsf")
1.2 逻辑错误
l = [1,2]
a = l[10]
res = 1/0
1.3 异常
1.4 异常类
常用异常类:
AssertionError--- assert(断言)语句失败
AttributeError--- 试图访问一个对象没有的属性,比如foo.x ,但是foo没有x这个属性
IOError---输入/输出异常,基本上是无法打开文件
ImportError---无法引入模块或者包,基本上是路径问题
IndentationError---语法错误,代码没有正确对齐
IndexError---下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
KeyError---试图访问字典里不存在的键
KerboardInterrupt---Ctrl + C 被按下
NameError---使用一个还未被赋值予对象的变量
SyntaxError---Python代码非法,代码不能解释
TypeError---传入对象类型与要求的不符
UnboundLocalError---试图访问一个还未被设置的局部变量,基本上是由于另一个同名的全局变量,导致你以为正在访问它
ValueError---传入一个调用者不期望的值,即使值的类型是正确的
二、异常处理
2.1什么是异常?
异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行。
一般情况下,在Python无法正常处理程序时就会发生一个异常。
异常是Python对象,表示一个错误。
2.2为什么进行异常处理?
当Python脚本发生异常时我们需要捕获处理它,否则程序会终止执行。
2.3异常处理
2.3.1使用if判断式
原代码1:
age = input('>>>:') #输入一个字符
int(age)
使用if判断进行异常处理:
if age.isdigest():
int(age) #主逻辑
elif age.isdigit():
print('--->用户输入的空格')
elif len(age) == 0:
print('--->用户输入的为空')
else:
print('其他的非法输入')
原代码2:
num = input('>>>:') #输入一个字符串
int(num)
再次使用if判断进行异常处理:
num = input('>>>:') #输入一个字符串
# int(num)
if num.isdigest():
int(num) #主逻辑
elif num.isdigit():
print('--->用户输入的空格')
elif len(num == 0:
print('--->用户输入的为空')
else:
print('其他的非法输入')
问题一:
可读性较差。每一段代码都需要重新写一段if,elif等。
问题二:
两种代码是同一种异常,处理太繁琐。
总结:
1)if判断式的异常处理只能针对某一段代码,不同段的相同类型需要重复使用if来进行处理。
2)该方法频繁的代码使程序的可读性很差。
3)但也是可以解决一些问题的。
def test():
print('test running')
choice_dic = {
'1':test
}
while Ture:
choice = input('>>>:').strip()
if not choice or choice not in choice_dic:countinue
choice_dic[choice]()
2.3.2 python提供一种特定的语法结构用来进行异常处理
1、基本语法:
try:
被检测的代码块
except 异常类型:
try中一旦检测到异常,就执行这个位置的逻辑
2、异常类智能用来处理指定的异常情况,如果非指定异常则无法处理
try:
num1 = input('1>>>:')
int(num1) #主逻辑
num2 = input('2>>>:')
int(num2) #主逻辑
except ValueError as a:
print(a) #输出异常值
若未捕捉到异常,则程序直接报错,当出现异常时,则不处理异常下面的代码。
3、多分支
try:
age = input('1>>>:')
int(age) # 主逻辑
num = input('2>>>:')
int(num) # 主逻辑
l = []
l[1000]
except KeyError as a:
print('>', a) # 输出异常值
except ValueError as b:
print('->', b)
except ValueError as c:
print('-->', c)
#未捕捉该异常时跳到下一判断,捕捉到该异常则该类型程序结束
print('00000')
对于不同类型定制不同的处理逻辑
4、万能异常:可以捕捉所有异常
try:
age = input('1>>>:')
int(age) # 主逻辑
num = input('2>>>:')
int(num) # 主逻辑
l = []
l[1000]
dic = {}
dic['name']
except Exception as d: #万能异常
print('___>', d)
不知道所属哪种类型的异常,可以在指定异常处理中充当其他异常
try:
age = input('1>>>:')
int(age)
except ValueError as b:
print('->', b)
except ValueError as c:
print('-->', c)
except Exception as d: #其他异常
print('___>', d)
5、异常的其他方法
try:
age = input('1>>>:')
int(age)
except ValueError as b:
print('->', b)
except ValueError as c:
print('-->', c)
#except Exception as d:
#print('___>', d)
else:
print('try内代码块没有异常,执行此语句')
finally:
print("无论是否有异常,都执行该模块,通常进行清理工作")
6、主动触发异常
try:
raise TypeError('错误类型')
except Exception as d:
print( d)
7、自定义异常
class EgonException(BaseException):
def __int__(self, msg):
self.msg = msg
def __str__(self):
return self.msg
try:
raise TypeError('类型错误')
except EgonException as a:
print(a)
8、断言
# assert 条件
# assert 1 == 1
# assert 1 == 2
print('-----')
assert 1 == 1
print('~~~~~')
def test1():
# '一堆逻辑'
res = 7
return 7
res =test()
assert res == 7 #对上面结果进行判断,异常则抛出异常值
#很多代码,跟在res进行下一步
9、使用tey...except的方式
1)把错误处理和真正的工作分开来
2)代码更易组织,更清晰,复杂的工作任务更容易实现
3)更安全,不至于由于一些小的疏忽而是程序意外崩溃
3、什么时候使用异常处理
try...except尽量少用,它本身就是你附加给你的程序的一种异常处理的逻辑,与你的工作是没有关系的。
这种语句实=使用多的话会导致代码可读性较差
只有在异常无法预知的情况下,才应该加上try...except,其他的逻辑错误应该尽量修正