博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
《pyhton学习手册》 第33章 异常编码细节
阅读量:6370 次
发布时间:2019-06-23

本文共 5215 字,大约阅读时间需要 17 分钟。

try/except/else语句

这些语句的一般的格式如下图所示

其中try中定义了主要执行的动作。except中定义了try语句当中发生异常的处理器。else定义了没有发生异常时候的处理器。

try语句运行的方式:try语句启动的时候,pyton会标识当前的程序环境,如果有异常发生,才返回这里。try首行下面的语句先被执行,然后根据执行的程序的情况,发生下面不同的动作:

-try里面的代码块的确发生异常,python就会跳回try,执行第一个符合引发异常的except字句下面的语句。当except执行后,控制权会到整个try语句后(try/except/else所有语句)继续执行。

-try里面的代码块发生异常,但是没有符合的except字据,那么异常会向上传递。

-try里面的代码没有异常,python会执行else行下的语句,控制权会在整个try语句下继续。

try语句分句

-在python2.5开始,finally可以和except和else出现在同一个语句当中,在2.5以前,finally只能单独的和try结合使用。

-excpet: 这种形式可以捕获任何形式的异常,是一种通用的功能。except Exception:  捕获一个名为Exception的异常,效果几乎和空的except具有相同的效果,但是忽略和系统退出相关的异常。

-一旦捕获了异常,控制权会在捕捉的地方继续向下(也就是在try之后),没有直接的方式可以回到异常发生的地方那个,可以运行下面的代码:

try:    print('A')    raise IndexError    print('B')except IndexError:    print('C')print('D')

 

输出结果如下:

ACD

 

可以发现,在捕获到IndexError异常以后,try语句里面的内容不会向下执行(即不会输出‘B’),而是在整个try语句后继续运行。

try/finally语句

-当try代码块当中有异常的时候,python会回来运行finally里面的代码块,但是紧接着会把异常向上传递,传到较高等级的try或者顶层默认处理器,程序不会在try语句下继续执行。和except不同的是,finally不会终止异常,而是在finally代码块执行后,一直处于发生状态

-try/finally最典型的另个应用场景是在关闭一个文件的时候, 或者关闭一个服务器连接的时候。

统一try/except/finally语句

在python2.5以前,try语句有两种形式,而且是独立的两种语句,finally无法和except和else混合,但是在2.5后的版本,这两个语句可以进行合并了,他们的形式如下:

 

合并try的例子

这里将通过一个聚合的例子来看一下前面说过的东西,代码如下:

sep = '-'* 32 +'\n'print(sep + 'Exception raised and caught')try:    x = 'spam'[20]except IndexError:    print('except run')finally:    print('finally run')print('after run')print(sep + 'No Exception rasied')try:    x = 'spam'[2]except IndexError:    print('except run')finally:    print('finally run')print('after run')print(sep+'No Exception raised with else')try:    x = 'spam'[2]except IndexError:    print('except run')else:    print('else run')finally:    print('finally run')print('after run')print(sep + 'Exception rasied but not caught')try:    x = 1 / 0except IndexError:    print('except run')finally:    print('finally run')print('after run')

 

运行结果如下:

--------------------------------Exception raised and caughtexcept runfinally runafter run--------------------------------No Exception rasiedfinally runafter run--------------------------------No Exception raised with elseelse runfinally runafter run--------------------------------Exception rasied but not caughtfinally runTraceback (most recent call last):  File "D:\application\eclipse\workspace\yichang\c2\test1.py", line 38, in 
x = 1 / 0ZeroDivisionError: division by zero

 raise语句

raise语句通常有三种形式

raise 
#raise 一个类的实例raise
#生成并且raise一个类的实例raise #raise最近生成的异常

raise总是引发一个类的实例,所以第一种方法是最常用的,在使用第二种方法的时候,调用了类的无参构造方法来生成类的一个实例,不加任何参数的raise产生最近生成的一个异常。

except name as X: 子句的作用:变量X将会分配给引发中所提供的实例,我们看下面的一个例子:

class MyExcp(Exception):    passtry:    raise MyExcp('nihao')except MyExcp as X:    print(X.args)

 

 

上面的例子当中,定义了我们自己的异常,在raise的时候,传入了参数'nihao',然后在捕获的时候捕获这个对象,输出这个对象的参数,最后的结果是: 

('nihao',) 

空的raise语句作用,它重新引发当前异常,运行如下代码:

try:    1/0except Exception as E:    print('nihao')    raise

 

得到结果:

nihaoTraceback (most recent call last):  File "D:\application\eclipse\workspace\yichang\c2\bb.py", line 2, in 
1/0ZeroDivisionError: division by zero

 

这个时候异常会继续上抛,如果没有raise,那么程序将在try后继续执行。

assert语句

assert可以看做是带有条件的raise语句,assert的一般语法是 assert <test>,<data>  当test的部分为错误(False)的时候,触发异常。

assert的一个作用是用来收集用户自定义的约束条件,因为python会自动帮我们收集程序当中出现的错误。

比如,当x ≥0的时候,触发一个错误,x ≥0 是我们自己定义的约束,运行如下代码:

def fun(x):    assert x < 0,'x must be negative'    return x ** 2fun(3)

 

输出结果如下:

Traceback (most recent call last):  File "D:\application\eclipse\workspace\yichang\c2\bb.py", line 4, in 
fun(3) File "D:\application\eclipse\workspace\yichang\c2\bb.py", line 2, in fun assert x < 0,'x must be negative'AssertionError: x must be negative

 

所以assert可以在我们检查我们程序定义的约束的时候起到很大的作用。

with/as环境管理器

with语句的基本格式如下:

with expection [as variable]:    with-block

 

如果有as variable的话,那么会接收内部__enter__返回出来参数。要实现环境管理器,使用with 方法,那么对象里面必须有__enter__和__exit__方法的。

我们来编写一个这样的类:

class TraceBlock:    def message(self):        print('message excute')    def __enter__(self):        print('enter excuete')        return self    def __exit__(self,type,value,tb):        if type is None:            print('exit normally\n')        else:            print('raise a excpetion')        #print('type:',type,'\nvalue:',value,'\ntb:',tb)with TraceBlock() as t:    t.message()    print('not error')with TraceBlock() as t:    t.message()    raise TypeError    print('error')

 

运行结果如下:

enter excuetemessage excutenot errorexit normallyenter excuetemessage excuteraise a excpetionTraceback (most recent call last):  File "D:\application\eclipse\workspace\yichang\c2\bb.py", line 18, in 
raise TypeErrorTypeError

 

 其实我们关系的是发生异常的时候,程序是怎么运行的,我们修改上面的代码

class TraceBlock:    def __enter__(self):        return self    def __exit__(self,type,value,tb):        print('type:',type,'\nvalue:',value,'\ntb:',tb)with TraceBlock() :    1/0

 

输出的结果如下:

type: 
value: division by zero tb:
Traceback (most recent call last): File "D:\application\eclipse\workspace\yichang\c2\bb.py", line 8, in
1/0ZeroDivisionError: division by zero

 

 说明,发生异常的时候,异常的参数会传入__exit__里面,在里面进行处理。


 

 总结:

   这一章讲了一些 try语句的细节,还有raise语句,assert语句以及with语句的细节。

 

转载于:https://www.cnblogs.com/jiaxin359/p/7302223.html

你可能感兴趣的文章
Flink - NetworkEnvironment
查看>>
BZOJ4374 : Little Elephant and Boxes
查看>>
【.Net Framework 体积大?】不安装.net framework 也能运行!?开篇叙述-1
查看>>
LLDP协议、STP协议 笔记
查看>>
如何使用 GroupBy 计数-Count()
查看>>
jquery之clone()方法详解
查看>>
Delphi 用文件流读取文本文件字符串的方法
查看>>
php中怎么导入自己写的类
查看>>
C# 委托
查看>>
Using Information Fragments to Answer the Questions Developers Ask
查看>>
JVM学习(4)——全面总结Java的GC算法和回收机制---转载自http://www.cnblogs.com/kubixuesheng/p/5208647.html...
查看>>
getParameter和getAttribute的区别
查看>>
自动工作负载库理论与操作(Automatic Workload Repository,AWR)
查看>>
Redis两种方式实现限流
查看>>
CentOS 7 中使用NTP进行时间同步
查看>>
在MongoDB数据库中查询数据(上)
查看>>
Python import其他文件夹的文件
查看>>
Jvm(22),回收策略-----标记清除算法
查看>>
MySQL多表关联查询效率高点还是多次单表查询效率高,为什么?
查看>>
UNIX 高手的 10 个习惯
查看>>