print("============异常与工具===================")
print("============一、异常基础===================")
"""
1、try/except
捕捉由 Python或你引起的异常并恢复。
2、try/finally
无论异常是否发生,执行清理行为。
3、raise
手动在代码中触发异常。
4、assert
有条件地在程序代码中触发异常。
5、with/as
在 Python2.6和后续版本中实现环境管理器(在2.5版中是可选功能)。
"""
def fetcher(obj,index):
return obj[index]
x='spam'
print(fetcher(x,3))
# try:
# fetcher(x,4)
# except IndexError:
# print('got exception')
def catcher():
try:
fetcher(x,4)
except IndexError:
print('got exception')
print('continuing')
catcher()
print("============1、用户异常的定义===================")
class Bad(Exception):
pass
def doomed():
raise Bad()
try:
doomed()
except Bad:
print('got Bad')
print("============2、终止行为===================")
try:
fetcher(x,3)
finally:
print('after fetch')
def after():
try:
fetcher(x,3)
finally:
print('after fetch')
print('after try?')
after()
with open('lumberjack.txt','w') as file:
file.write('The larch!\n')
"""
本章习题
1.说出异常处理的3个优点。
2.如果你不想做任何特殊的事情来处理异常,那么异常会发生什么呢?
3.如何从一个异常恢复你的脚本?
4.说出在脚本中触发异常的两种方式。
5.指出两种方式:不管异常是否发生,它们用来指定最终运行的行为。
"""
"""
1.异常处理对于错误处理、终止动作和事件通知有用。它可以简化特殊情况的处理,并且可以用来实现替代的控制流程。一般来讲,异常处理还可以减少程序所需的检
测错误代码的数量,因为所有的错误都由处理器来过滤,你可能不需要测试每个操作的输出。
2.任何未捕获的异常最终都流入默认的异常处理器, Python在程序的最顶端提供了它。这个处理器打印出类似的出错消息,并且退出程序。
3.如果你不想要默认消息和退出,可以编写ry/except语句来捕获并从触发的异常恢复。一旦捕获了一个异常,该异常将终止,并且程序继续。
4. raiseassert和语句可以用来触发一个异常,就好像该异常已经由 Python自身引
发。原则上讲,我们可以通过生成一个程序错误来引发异常,但是,这通常不是一个明确的目标。
5.try y/finally语句可以用来确保在一个代码块退出后执行的操作,而不管它是否会引
发一个异常。with/as语句也可以用来确保要运行的终止操作,但是,只有当处理的对象类型支持它的时候才可用。
"""
print("============二、异常编码细节===================")
"""
try:
#Run this main action first
except :
#Run if name1 is raised during try block
except(name2, name3):
#Run if any of these exceptions occur
except as :
#Run if name4 is raised, and get instance raised
except:
#Run for allother) exceptions raised
else:
#Run if no exception was raised during try block
except分句会捕捉异常, finally分句最后一定会执行,而如果没遇上异常,else分句就会执行。
"""
"""
try语句分句形式
分句形式 说明
except: 捕捉所有(其他)异常类型
except name: 只捕捉特定的异常
except name, value: 捕捉所列的异常和其额外的数据(或实例)
except(name1, name2): 捕捉任何列出的异常
except(name1,name2), value:捕捉任何列出的异常,并取得其额外数据
else: 如果没有引发异常,就运行
finally: 总是会运行此代码块
"""
# class MyError(Exception):pass
# def stuff(file):
# raise MyError()
# file= open('data','w')
# try:
# stuff(file)
# finally:
# file.close()
# print('not reached')
print("============三、统一try/exception/finally语句===================")
# try:
# main-action
# except Exception1:
# handler1
# except Exception1:
# handler2
# ...
# else:
# else-block
# finally:
# finally-block
"""
try --- except --- else --- finally
"""
print("============四、合并Try的例子===================")
sep = '-'*32+'\n'
print(sep+'Exception Raise And Caught')
try:
x='spam'[99]
except IndexError:
print('except run')
finally:
print('finally run')
print('after run')
print(sep + 'No Exception Raise')
try:
x='spam'[3]
except IndexError:
print('except run')
finally:
print('finally run')
print('after run')
print(sep + 'No Exception,With Else')
try:
x='spam'[3]
except IndexError:
print('except run')
else:
print('else run')
finally:
print('finally run')
print('after run')
print(sep + 'Exception Raise But Not Caught')
try:
x=1 / 0
except ZeroDivisionError:
print('except run')
finally:
print('finally run')
print('after run')
print("============五、环境管理协议===================")
# class TraceBlock:
# def message(self,arg):
# print('running',arg)
# def __enter__(self):
# print('starting with block')
# return self
# def __exit__(self, exc_type, exc_val, exc_tb):
# if exc_type is None:
# print('exited nomally\n')
# else:
# print('raise an exception!',exc_type)
# return False
# with TraceBlock() as action:
# action.message('test 1')
# print('reached')
#
# with TraceBlock() as action:
# action.message('test 2')
# raise TypeError
# print('not reached')
print("============二、异常对象===================")
"""
使用 raise语句主动抛出异常的意思是开发者可以自己制造程序异常,这里的程序异常不是指发生了内存溢出、列表越界访问等系统异常,而是指程序在执行过程中,发生
了用户输入的数据与要求数据不符、用户操作错误等问题,这些问题都需要程序进行处理并给出相应的提示。处理这些问题多使用判断语句,在判断语句体内进行相应的
问题处理,如果处理问题的语句过多,就会导致代码复杂化,代码结构不够清晰。在这种情况下,可以使用 raise语句主动抛出异常,由异常处理语句块进行处理。
"""
#用户登录判断,登录窗口设置
try:
print("请输入登录账号:")
username= input(">>:")
if username !="John":
raise Exception("用户名输入错误,请重新输入:")
print("请输入登录密码:")
psw= input(">>:")
if(psw !="123456"):
raise Exception("密码输入错误,请重新输入")
except Exception as e:
print(e)
print("============三、为什么使用类异常===================")
# class General(Exception):pass
# class Specific1(General):pass
# class Specific2(General):pass
#
# try:
# func()
# except(General,Specific1,Specific2):
# ...
"""
1、BaseException 异常的顶级根类
2、Exception 与应用相关的异常的顶层根超类,这是BaseException的一个直接子类,并且是所有其他内置异常的超类,除了系统退出事件类之外(SystemExit、
KeyboardInterruptGeneratorExit和)几乎所有的用户定义的类都应该继承自这个类,而不是BaseException。当遵从这一惯例的时候,在一条try语句的处理
器中指明 Exception,会确保你的程序将捕获除了系统退出事件之外的所有异常,通常该事件是允许通过的。实际上, Exception变成了try语句中的一个全捕获,
并且比一条空的 except更精确。
3、ArithmeticError:所有数值错误的超类(并且是Exception的一个子类)。
4、OverflowError:识别特定的数值错误的子类。
"""
# class FormatError(Exception):
# logfile = 'fomaterror.txt'
# def __init__(self,line,file):
# self.line = line
# self.file = file
# def logerror(self):
# log = open(self.logfile,'a')
# print('Error at',self.file,self.line,file=log)
# def parser():
# raise FormatError(40,'spam.txt')
# try:
# parser()
# except FormatError as exc:
# exc.logerror()
def action2():
print(1+[])
def action1():
try:
action2()
except TypeError:
print('inner try')
try:
action1()
except TypeError:
print('outer try')
print("============四、语法嵌套化==================")
try:
try:
action2()
except TypeError:
print('inner try')
except TypeError:
print('outer try')