程序出错
程序交给操作系统运行。程序内部出错,那么操作系统运行时,就会终止程序,并把错误抛出
程序产生的异常
语法错误
python解释器的语法检测就过不去,程序不会执行,要找出错误,修改代码
def test:
print("666")
逻辑错误
程序执行到错误逻辑报错
num = 22
num2 = input("number:").strip()
if num == int(num2):
print("相等")
else:
print("不相等")
这种错误发生的条件是可预知的,我们需要用if进行处理:要在错误发生之前进行预防
num=22
while True:
num2=input('>>: ').strip()
if num2.isdigit(): #只有在age为字符串形式的整数时,下列代码才不会出错,该条件是可预知的
num3=int(num2)
if num3 == num:
print('相等')
break
处理异常
对于用户交互的程序,无法控制用户的操作,不可控的行为会导致服务端链接异常,需要处理
如果错误发生的条件是不可预知的,则需要用到try...except:在错误发生之后进行处理
如果可能异常的代码出现了要捕捉的异常类型,那么久会执行定义的处理代码,否则一样会由操作系统抛出
try:
可能异常的代码
except 异常类型 as e: # as: 如果出现异常,把异常的值赋值给e
处理代码
如下,异常类型不是KeyError,系统抛异常
try:
n = input(":").strip()
x = int(n)
print(x)
except KeyError:
print("111")
# :aa
# Traceback (most recent call last):
# File "E:/workspace/selenium2/demo1.py", line 12, in <module>
# x = int(n)
# ValueError: invalid literal for int() with base 10: 'aa'
捕捉ValueError,成功捕获并处理
try:
n = input(":").strip()
x = int(n)
print(x)
except ValueError:
print("111")
# :aa
# 111
捕获异常、断言、自己引发异常、自定义异常
#1 异常类只能用来处理指定的异常情况,如果非指定异常则无法处理。
s1 = 'hello'
try:
int(s1)
except IndexError as e: # 未捕获到异常,程序直接报错
print e
#2 多分支
s1 = 'hello'
try:
int(s1)
except IndexError as e:
print(e)
except KeyError as e:
print(e)
except ValueError as e:
print(e)
#3 万能异常Exception
s1 = 'hello'
try:
int(s1)
except Exception as e:
print(e)
#4 多分支异常与万能异常
#4.1 如果你想要的效果是,无论出现什么异常,我们统一丢弃,或者使用同一段代码逻辑去处理他们,那么骚年,大胆的去做吧,只有一个Exception就足够了。
#4.2 如果你想要的效果是,对于不同的异常我们需要定制不同的处理逻辑,那就需要用到多分支了。
#5 也可以在多分支后来一个Exception
s1 = 'hello'
try:
int(s1)
except IndexError as e:
print(e)
except KeyError as e:
print(e)
except ValueError as e:
print(e)
except Exception as e:
print(e)
#6 异常的其他结构
s1 = 'hello'
try:
int(s1)
except IndexError as e:
print(e)
except KeyError as e:
print(e)
except ValueError as e:
print(e)
except Exception as e:
print(e)
else:
print('try内代码块没有异常则执行我')
finally:
print('无论异常与否,都会执行该模块,通常是进行清理工作')
#7 主动触发异常
try:
raise TypeError('类型错误')
except Exception as e:
print(e)
#8 自定义异常
class EgonException(BaseException):# 所有的异常类型都是继承BaseException
def __init__(self,msg):
self.msg=msg
def __str__(self):
return self.msg
try:
raise EgonException('类型错误') # raise 用于抛出异常
except EgonException as e:
print(e)
#9 断言:assert 条件
assert 1 == 1
assert 1 == 2
x=9
y=6
assert x>y # 断定x>y 成立就继续执行
assert x<y # 断定x<y 不成立抛出异常
# 用于调试,看程序运行结果是否符合预期
# 与if判断不同,if不会妨碍后续程序的执行, 虽然断言也是用来判断,但是成立的话,程序会正常执行,不成立的话程序会终止,抛异常
#10 总结try..except
1:把错误处理和真正的工作分开来
2:代码更易组织,更清晰,复杂的工作任务更容易实现;
3:毫无疑问,更安全了,不至于由于一些小的疏忽而使程序意外崩溃了;
常见的异常类型
AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x
IOError 输入/输出异常;基本上是无法打开文件
ImportError 无法引入模块或包;基本上是路径问题或名称错误
IndentationError 语法错误(的子类) ;代码没有正确对齐
IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
KeyError 试图访问字典里不存在的键
KeyboardInterrupt Ctrl+C被按下
NameError 使用一个还未被赋予对象的变量
SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了)
TypeError 传入对象类型与要求的不符合
UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,
导致你以为正在访问它
ValueError 传入一个调用者不期望的值,即使值的类型是正确的
例子
拿到文件句柄f,执行close后,操作系统会把内存中的文件关闭掉,但是程序中的f还是存在的,依然可以调用其下方法,执行write时,就出现IO异常
f = open("test.txt", "w", encoding="utf-8")
print(f) # <_io.TextIOWrapper name='test.txt' mode='w' encoding='utf-8'>
f.close()
print(f) # <_io.TextIOWrapper name='test.txt' mode='w' encoding='utf-8'>
f.write("6666")
# Traceback (most recent call last):
# <_io.TextIOWrapper name='test.txt' mode='w' encoding='utf-8'>
# File "E:/workspace/selenium2/demo1.py", line 15, in <module>
# <_io.TextIOWrapper name='test.txt' mode='w' encoding='utf-8'>
# f.write("6666")
# ValueError: I/O operation on closed file.
反之,在程序中删除f,程序级别的f不在了,但是打开的文件还在内存中占着资源
f = open("test.txt", "w", encoding="utf-8")
print(f)
del f
print(f)
# Traceback (most recent call last):
# File "E:/workspace/selenium2/demo1.py", line 13, in <module>
# <_io.TextIOWrapper name='test.txt' mode='w' encoding='utf-8'>
# print(f)
# NameError: name 'f' is not defined
按道理来说,不管怎么样,都要执行f.close()操作,但是如果在执行它之前,程序出错了就停止了,f这个对象就被回收了了,但是这个关闭操作不会被执行,那么就跟上面的情况是一样的,打开的文件还在内存中占着资源
f = open("test.txt", "w", encoding="utf-8")
print(int("aaa"))
f.close()
检查可能出现异常的代码,不管出现还是不出现,都要执行关闭操作,回收资源
try:
f = open("test.txt", "w", encoding="utf-8")
print(int("aaa"))
finally:
print("执行关闭")
f.close()
这里有一个绝招,在程序的开头加上try,末尾加上except,那么你的程序就没有一个bug了~~~~~~
注意吧:
异常处理用于无法控制的肯定出现的异常进行处理,但是原则上能预防的就预防,尽量不用异常处理,异常处理的代码跟真实的程序代码是没有关系的,用的多了会影响程序运行的效率,让你的程序可读性变差,不是用来擦屁股的