53----异常处理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/c_first/article/details/82230231

程序出错

程序交给操作系统运行。程序内部出错,那么操作系统运行时,就会终止程序,并把错误抛出


程序产生的异常

语法错误

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了~~~~~~

注意吧:

异常处理用于无法控制的肯定出现的异常进行处理,但是原则上能预防的就预防,尽量不用异常处理,异常处理的代码跟真实的程序代码是没有关系的,用的多了会影响程序运行的效率,让你的程序可读性变差,不是用来擦屁股的

 

猜你喜欢

转载自blog.csdn.net/c_first/article/details/82230231
53
今日推荐