Python异常 - littleboy12580/learning_python GitHub Wiki

异常处理

默认异常处理器

即Python自动抛出的内置的异常;打印标准出错信息,这个信息包括引发的异常还有堆栈跟踪(即异常发生时激活的程序行和函数清单)

异常捕获

try/except语句

通过执行try代码块来触发异常,此时python会自动跳至处理器,在except分句执行后会回到代码中继续向下执行

def catcher():
    try:
        fetcher(x,4)
    except IndexError:
        print('got exception')
    print('continue')
catcher()

运行结果为

got exception
continuing

一个try语句块可以抛出多个异常

try:
     x = input('Enter the first number: ')
     y = input('Enter the second number: ')
     print x/y
except ZeroDivisionError:
     print "The second number can't be zero!"
except TypeError:
     print "That wasn't a number, was it?"

一个except语句可以捕获多个异常

try:
     x = input('Enter the first number: ')
     y = input('Enter the second number: ')
     print x/y
except (ZeroDivisionError, TypeError, NameError):  #此时except语句后面需要加上小括号
     print 'Your numbers were bogus...'

访问捕捉到的异常对象并将异常信息打印输出

try:
     x = input('Enter the first number: ')
     y = input('Enter the second number: ')
     print x/y
except (ZeroDivisionError, TypeError), e:
     print e

捕捉全部异常,防止漏掉无法预测的异常情况

try:
     x = input('Enter the first number: ')
     y = input('Enter the second number: ')
     print x/y
except :
     print 'Someting wrong happened...'

try/except/else语句

除了使用except子句,还可以使用else子句,如果try块中没有引发异常,else子句就会被执行

while 1:
     try:
         x = input('Enter the first number: ')
         y = input('Enter the second number: ')
         value = x/y
         print 'x/y is', value
     except:
         print 'Invalid input. Please try again.'
     else:
         break

try/finally语句

不论try子句中是否发生异常情况,finally子句肯定会被执行,也可以和else子句一起使用。finally子句常用在程序的最后关闭文件或网络套接字。

try:
     1/0
 except:
     print 'Unknow variable'
 else:
     print 'That went well'
 finally:
     print 'Cleaning up'

显式触发异常

raise语句

使用raise语句来手动抛出一个异常,raise后面跟上Exception异常类或者Exception的子类,还可以在Exception的括号中加入异常的信息。

filename = raw_input('please input file name:')
if filename=='hello':
    raise NameError('input file name error !')

Exception类是所有异常类的基类,我们还可以根据该类创建自己定义的异常类

class SomeCustomException(Exception): pass

assert语句

assert语句相当于条件式的raise语句,其基本形式为

assert <test>, <data>

执行起来就像如下的代码

if __debug__:
    if not <test>:
        raise AseertionError(<data>)

即如果test计算为假,Python就会引发异常,data项则是异常的额外数据

上下文管理器

即with/as环境管理器,with/as语句的设计是作为try/finally用法模式的替代方案,它支持更丰富的基于对象的协议,可以为代码块定义支持进入和离开动作,其基本用法为

with open("new.txt", "w") as f:
    print(f.closed)
    f.write("Hello World!")
print(f.closed)

当我们使用上下文管理器的语法时,我们实际上要求Python在进入程序块之前调用对象的__enter__()方法,在结束程序块的时候调用__exit__()方法。因此任何定义了__enter__()和__exit__()方法的对象都可以用于上下文管理器,具体实现为:

  • enter(self): 进入上下文管理器时调用此方法,其返回值将被放入with-as语句中as说明符指定的变量中。
  • exit(self,type,value,tb):离开上下文管理器调用此方法。如果有异常出现,type、value、tb分别为异常的类型、值和追踪信息。如果没有异常,3个参数均设为None。

此方法返回值为True或者False,分别指示被引发的异常得到了还是没有得到处理。如果返回False,引发的异常会被传递出上下文。

上文代码的文件上下文管理器具体实现为:

class OpenFile(object):
    def __init__(self,filename,mode):
        self.filename=filename
        self.mode=mode
    def __enter__(self):
        self.f=open(self.filename,self.mode)
        return self.f  #作为as说明符指定的变量的值
    def __exit__(self,type,value,tb):
        self.f.close()
        return False   #异常会被传递出上下文

多重异常的处理

可以在try语句中嵌套另一个try语句,一旦发生异常,python匹配最近的except语句;若是内部except能够处理该异常,则外围try语句不会捕获异常;若是不能,或者忽略,外围try处理

def action2():
    print(1+[])
def action1():
    try:
        action2()
    except TypeError:
        print('inner try')
try:
    action1()
except TypeError:
    print('outer try')

最后的运行结果为 inner try

⚠️ **GitHub.com Fallback** ⚠️