简单介绍Python中的try和finally和with方法

来源:本网整理

给你看我以前的回答吧http://.baidu.com/question/224604501.html请问您学会python有什么收获?http://.baidu.com/question/225515564.html如何从零开始学习PYTHONhttp://.baidu.com/question/225455239.htmlpython擅长干什么?能干什么?http://.baidu.com/question/226460954.htmlPython语言,没用过Python也进来看看www.zgxue.com防采集请勿采集本网。

用 Python 做一件很平常的事情: 打开文件, 逐行读入, 最后关掉文件; 进一步的需求是, 这也许是程序中一个可选的功能, 如果有任何问题, 比如文件无法打开, 或是读取出错, 那么在函数内需要捕获所有异常, 输出一行警告并退出. 代码可能一开始看起来是这样的

使用bsddb模块的xxopen方法以后,就可以像字典一样访问 python manual 里的例子 import bsddb db=bsddb.btopen('/tmp/spam.db ','c ') for i in range(10):db['%d '%i]='%d '%(i*i) db['3 ']

 

Python是一种脚本语言,因为有丰富的Python库,从而是Python的功能非常强大,你可以参考 http://baike.baidu.com/view/21087.htm

Python,是一种面向对象的解释型计算机程序设计语言,具有丰富和强大的库,Python 已经成为继Java,C++之后的的第三大语言。特点:简单易学、免费开源、高层语言、可移植性强、面向对象、可扩展性

def read_file(): try: f = open('yui', 'r') print ''.join(f.readlines()) except: print 'error occurs while reading file' finally: f.close()

我从入门Python到现在也没有多少时间,所以写如此大的一个题目必定会引发各种批判,当然我没有想造一个大新闻,只是想根据自己的学习历程做一个简单的总结,同时将这三个阶段对应的一些好的书籍简单介绍

    不过这显然无法运作, 因为  f  是在  try  块中定义的, 而在  finally  中无法引用.

jython是用java写的python解释器,用jython解释的python程序可以调用java写的拓展库

    如果将  f  提取到  try  块外部, 如

 

Python是一种脚本语言,因为有丰富的Python库,从而是Python的功能非常强大,你可以参考 http://baike.baidu.com/view/21087.htm

Python,是一种面向对象的解释型计算机程序设计语言,具有丰富和强大的库,Python 已经成为继Java,C++之后的的第三大语言。特点:简单易学、免费开源、高层语言、可移植性强、面向对象、可扩展性

def read_file(): f = open('azusa', 'r') try: print ''.join(f.readlines()) except: print 'error occurs while reading file' finally: f.close()

那么, 问题在于当打开文件失败, 抛出异常将不会被捕获.

    挫一点的方法自然是, 再套一层  try  吧

 

Python是一种脚本语言,因为有丰富的Python库,从而是Python的功能非常强大,你可以参考 http://baike.baidu.com/view/21087.htm

Python,是一种面向对象的解释型计算机程序设计语言,具有丰富和强大的库,Python 已经成为继Java,C++之后的的第三大语言。特点:简单易学、免费开源、高层语言、可移植性强、面向对象、可扩展性

def read_file(): try: f = open('sawako', 'r') try: print ''.join(f.readlines()) except: print 'error occurs while reading file' finally: f.close() except: print 'error occurs while reading file'

    当然这不仅仅是多一层缩进挫了, 连警告输出都白白多一次呢.

    正规一点的方式是, 使用 Python 引入的  with  结构来解决, 如

 

Python是一种脚本语言,因为有丰富的Python库,从而是Python的功能非常强大,你可以参考 http://baike.baidu.com/view/21087.htm

Python,是一种面向对象的解释型计算机程序设计语言,具有丰富和强大的库,Python 已经成为继Java,C++之后的的第三大语言。特点:简单易学、免费开源、高层语言、可移植性强、面向对象、可扩展性

def readFile(): try: with open('mio', 'r') as f: print ''.join(f.readlines()) except: print 'error occurs while reading file'

    当文件打开失败时, 异常自然会被  except  到; 否则, 在  with  块结束之后, 打开的文件将自动关闭.

    除了打开文件, 还有其它这样可以用于  with  的东西么? 或者说, 怎么自定义一个什么东西, 让它能用于  with 呢?

 

Python是一种脚本语言,因为有丰富的Python库,从而是Python的功能非常强大,你可以参考 http://baike.baidu.com/view/21087.htm

   直接回答后一个问题吧, 秘密在于 Python 虚拟机在  with  块退出时会去寻找对象的  __exit__  方法并调用它, 把释放资源的动作放在这个  __exit__  函数中就可以了; 另外, 对象还需要一个  __enter__  函数, 当进入  with 块时, 这个函数被调用, 而它的返回值将作为  as  后引用的值. 一个简单的例子是

 

Python是一种脚本语言,因为有丰富的Python库,从而是Python的功能非常强大,你可以参考 http://baike.baidu.com/view/21087.htm

Python,是一种面向对象的解释型计算机程序设计语言,具有丰富和强大的库,Python 已经成为继Java,C++之后的的第三大语言。特点:简单易学、免费开源、高层语言、可移植性强、面向对象、可扩展性

class Test: def __init__(self): print 'init' def __enter__(self): print 'enter' return self def __exit__(self, except_type, except_obj, tb): print except_type print except_obj import traceback print ''.join(traceback.format_tb(tb)) print 'exit' return True with Test() as t: raise ValueError('kon!')

    执行这一段代码, 输出将会是

 

Python是一种脚本语言,因为有丰富的Python库,从而是Python的功能非常强大,你可以参考 http://baike.baidu.com/view/21087.htm

Python,是一种面向对象的解释型计算机程序设计语言,具有丰富和强大的库,Python 已经成为继Java,C++之后的的第三大语言。特点:简单易学、免费开源、高层语言、可移植性强、面向对象、可扩展性

init enter <type 'exceptions.ValueError'> kon! File "test.py", line 17, in <module> raise ValueError('kon!') exit

     __exit__  函数接受三个参数, 分别是异常对象类型, 异常对象和调用栈. 如果  with  块正常退出, 那么这些参数将都是  None . 返回  True  表示发生的异常已被处理, 不再继续向外抛出.

    简单的介绍到此为止, 详细的情况可以参考  PEP 343  (这数字真不错, 7 3 ).

下面介绍下 with 语句的实例用法 & 高级用法:

Python高端、大气、上档次的with语句

在说with语句之前,先看看一段简单的代码吧

 

Python是一种脚本语言,因为有丰富的Python库,从而是Python的功能非常强大,你可以参考 http://baike.baidu.com/view/21087.htm

Python,是一种面向对象的解释型计算机程序设计语言,具有丰富和强大的库,Python 已经成为继Java,C++之后的的第三大语言。特点:简单易学、免费开源、高层语言、可移植性强、面向对象、可扩展性

lock = threading.Lock()...lock.acquire()elem = heapq.heappop(heap)lock.release()

很简单直观,多个线程共用一个优先级队列的时候,首先先用互斥锁lock.acquire()把优先级队列锁上,然后取元素,再然后lock.release()释放这个锁。

虽然看似非常符合逻辑的一个过程,但是里面隐藏着一个巨大的bug:当heap里面没有元素的时候,会抛出一个IndexError异常,再然后堆栈回滚,再然后lock.release()根本不会执行,这个锁就永远得不到释放,因此就发生了喜闻乐见的死锁问题。这个也是很多大神们讨厌异常的原因。经典Java风格的解决方案就是

 

Python是一种脚本语言,因为有丰富的Python库,从而是Python的功能非常强大,你可以参考 http://baike.baidu.com/view/21087.htm

Python,是一种面向对象的解释型计算机程序设计语言,具有丰富和强大的库,Python 已经成为继Java,C++之后的的第三大语言。特点:简单易学、免费开源、高层语言、可移植性强、面向对象、可扩展性

lock = threading.Lock()...lock.acquire()try: elem = heapq.heappop(heap)finally: lock.release()

这个虽然可以,但是怎么看怎么dirty,和Python优雅、简单的风格出入很大。其实,自从Python2.5开始引入了with语句,一切就变得非常简单:

 

Python是一种脚本语言,因为有丰富的Python库,从而是Python的功能非常强大,你可以参考 http://baike.baidu.com/view/21087.htm

Python,是一种面向对象的解释型计算机程序设计语言,具有丰富和强大的库,Python 已经成为继Java,C++之后的的第三大语言。特点:简单易学、免费开源、高层语言、可移植性强、面向对象、可扩展性

lock = threading.Lock()...with lock: elem = heapq.heappop(heap)

在此无论以何种方式离开with语句的代码块,锁都会被释放。

with语句的设计目的就是为了使得之前需要通过try...finally解决的清理资源问题变得简单、清晰,它的的用法是

 

Python是一种脚本语言,因为有丰富的Python库,从而是Python的功能非常强大,你可以参考 http://baike.baidu.com/view/21087.htm

Python,是一种面向对象的解释型计算机程序设计语言,具有丰富和强大的库,Python 已经成为继Java,C++之后的的第三大语言。特点:简单易学、免费开源、高层语言、可移植性强、面向对象、可扩展性

with expression [as variable]: with-block

其中expression返回一个叫做「context manager」的对象,然后这个对象被赋给variable(如果有的话)。「context manager」对象有两个方法,分别是__enter__()和__exit__(),很明显一个在进入with-block时调用,一个离开with-block的时候调用。

这样的对象不需要自己去实现,在Python标准库里面很多API都是已经实现了这两个方法,最常见的一个例子就是读写文件的open语句。

 

Python是一种脚本语言,因为有丰富的Python库,从而是Python的功能非常强大,你可以参考 http://baike.baidu.com/view/21087.htm

Python,是一种面向对象的解释型计算机程序设计语言,具有丰富和强大的库,Python 已经成为继Java,C++之后的的第三大语言。特点:简单易学、免费开源、高层语言、可移植性强、面向对象、可扩展性

with open('1.txt', encoding = 'utf-8') as fp: lines = fp.readlines()

无论是正常离开还是因为异常原因离开with语句块,打开的文件资源总是会释放。

接下去讨论一下with语句配合contextlib库的一些比较实用的方法,比如需要同时打开两个文件,一个读一个写,这个时候就可以这样写:

 

Python是一种脚本语言,因为有丰富的Python库,从而是Python的功能非常强大,你可以参考 http://baike.baidu.com/view/21087.htm

Python,是一种面向对象的解释型计算机程序设计语言,具有丰富和强大的库,Python 已经成为继Java,C++之后的的第三大语言。特点:简单易学、免费开源、高层语言、可移植性强、面向对象、可扩展性

from contextlib import nested...with nested(open('in.txt'), open('out.txt', 'w')) as (fp_in, fp_out): ...

这样就可以省掉两个with的语句的嵌套了,另外如果遇到一些还没有支持「context manager」的API呢?比如urllib.request.urlopen(),这个返回的对象因为不是「context manager」,结束的时候还需要自己去调用close方法。

类似这种API,contextlib提供了一个叫做closing方法,它会在离开with语句的时候,自动调用对象的close方法,因此urlopen也可以这样写:

 

Python是一种脚本语言,因为有丰富的Python库,从而是Python的功能非常强大,你可以参考 http://baike.baidu.com/view/21087.htm

Python,是一种面向对象的解释型计算机程序设计语言,具有丰富和强大的库,Python 已经成为继Java,C++之后的的第三大语言。特点:简单易学、免费开源、高层语言、可移植性强、面向对象、可扩展性

from contextlib import closing...with closing(urllib.request.urlopen('http://www.yahoo.com')) as f: for line in f: sys.stdout.write(line)

 用 Python 做一件很平常的事情: 打开文件, 逐行读入, 最后关掉文件; 进一步的需求是, 这也许是程序中一个可选的功能, 如果有任何问题, 比如文件无法打开, 或是读取出错, 那么在函数内需要捕获所有异常, 输出一行警告并退出. 代码可能一开始看起来是这样的

 

Python是一种脚本语言,因为有丰富的Python库,从而是Python的功能非常强大,你可以参考 http://baike.baidu.com/view/21087.htm

Python,是一种面向对象的解释型计算机程序设计语言,具有丰富和强大的库,Python 已经成为继Java,C++之后的的第三大语言。特点:简单易学、免费开源、高层语言、可移植性强、面向对象、可扩展性

def read_file(): try: f = open('yui', 'r') print ''.join(f.readlines()) except: print 'error occurs while reading file' finally: f.close()

我从入门Python到现在也没有多少时间,所以写如此大的一个题目必定会引发各种批判,当然我没有想造一个大新闻,只是想根据自己的学习历程做一个简单的总结,同时将这三个阶段对应的一些好的书籍简单介绍

    不过这显然无法运作, 因为  f  是在  try  块中定义的, 而在  finally  中无法引用.

jython是用java写的python解释器,用jython解释的python程序可以调用java写的拓展库

    如果将  f  提取到  try  块外部, 如

 

Python是一种脚本语言,因为有丰富的Python库,从而是Python的功能非常强大,你可以参考 http://baike.baidu.com/view/21087.htm

Python,是一种面向对象的解释型计算机程序设计语言,具有丰富和强大的库,Python 已经成为继Java,C++之后的的第三大语言。特点:简单易学、免费开源、高层语言、可移植性强、面向对象、可扩展性

def read_file(): f = open('azusa', 'r') try: print ''.join(f.readlines()) except: print 'error occurs while reading file' finally: f.close()

那么, 问题在于当打开文件失败, 抛出异常将不会被捕获.

    挫一点的方法自然是, 再套一层  try  吧

 

Python是一种脚本语言,因为有丰富的Python库,从而是Python的功能非常强大,你可以参考 http://baike.baidu.com/view/21087.htm

Python,是一种面向对象的解释型计算机程序设计语言,具有丰富和强大的库,Python 已经成为继Java,C++之后的的第三大语言。特点:简单易学、免费开源、高层语言、可移植性强、面向对象、可扩展性

def read_file(): try: f = open('sawako', 'r') try: print ''.join(f.readlines()) except: print 'error occurs while reading file' finally: f.close() except: print 'error occurs while reading file'

    当然这不仅仅是多一层缩进挫了, 连警告输出都白白多一次呢.

    正规一点的方式是, 使用 Python 引入的  with  结构来解决, 如

 

Python是一种脚本语言,因为有丰富的Python库,从而是Python的功能非常强大,你可以参考 http://baike.baidu.com/view/21087.htm

Python,是一种面向对象的解释型计算机程序设计语言,具有丰富和强大的库,Python 已经成为继Java,C++之后的的第三大语言。特点:简单易学、免费开源、高层语言、可移植性强、面向对象、可扩展性

def readFile(): try: with open('mio', 'r') as f: print ''.join(f.readlines()) except: print 'error occurs while reading file'

    当文件打开失败时, 异常自然会被  except  到; 否则, 在  with  块结束之后, 打开的文件将自动关闭.

    除了打开文件, 还有其它这样可以用于  with  的东西么? 或者说, 怎么自定义一个什么东西, 让它能用于  with 呢?

 

Python是一种脚本语言,因为有丰富的Python库,从而是Python的功能非常强大,你可以参考 http://baike.baidu.com/view/21087.htm

   直接回答后一个问题吧, 秘密在于 Python 虚拟机在  with  块退出时会去寻找对象的  __exit__  方法并调用它, 把释放资源的动作放在这个  __exit__  函数中就可以了; 另外, 对象还需要一个  __enter__  函数, 当进入  with 块时, 这个函数被调用, 而它的返回值将作为  as  后引用的值. 一个简单的例子是

 

Python是一种脚本语言,因为有丰富的Python库,从而是Python的功能非常强大,你可以参考 http://baike.baidu.com/view/21087.htm

Python,是一种面向对象的解释型计算机程序设计语言,具有丰富和强大的库,Python 已经成为继Java,C++之后的的第三大语言。特点:简单易学、免费开源、高层语言、可移植性强、面向对象、可扩展性

class Test: def __init__(self): print 'init' def __enter__(self): print 'enter' return self def __exit__(self, except_type, except_obj, tb): print except_type print except_obj import traceback print ''.join(traceback.format_tb(tb)) print 'exit' return True with Test() as t: raise ValueError('kon!')

    执行这一段代码, 输出将会是

 

Python是一种脚本语言,因为有丰富的Python库,从而是Python的功能非常强大,你可以参考 http://baike.baidu.com/view/21087.htm

Python,是一种面向对象的解释型计算机程序设计语言,具有丰富和强大的库,Python 已经成为继Java,C++之后的的第三大语言。特点:简单易学、免费开源、高层语言、可移植性强、面向对象、可扩展性

init enter <type 'exceptions.ValueError'> kon! File "test.py", line 17, in <module> raise ValueError('kon!') exit

     __exit__  函数接受三个参数, 分别是异常对象类型, 异常对象和调用栈. 如果  with  块正常退出, 那么这些参数将都是  None . 返回  True  表示发生的异常已被处理, 不再继续向外抛出.

    简单的介绍到此为止, 详细的情况可以参考  PEP 343  (这数字真不错, 7 3 ).

下面介绍下 with 语句的实例用法 & 高级用法:

Python高端、大气、上档次的with语句

在说with语句之前,先看看一段简单的代码吧

 

Python是一种脚本语言,因为有丰富的Python库,从而是Python的功能非常强大,你可以参考 http://baike.baidu.com/view/21087.htm

Python,是一种面向对象的解释型计算机程序设计语言,具有丰富和强大的库,Python 已经成为继Java,C++之后的的第三大语言。特点:简单易学、免费开源、高层语言、可移植性强、面向对象、可扩展性

lock = threading.Lock()...lock.acquire()elem = heapq.heappop(heap)lock.release()

很简单直观,多个线程共用一个优先级队列的时候,首先先用互斥锁lock.acquire()把优先级队列锁上,然后取元素,再然后lock.release()释放这个锁。

虽然看似非常符合逻辑的一个过程,但是里面隐藏着一个巨大的bug:当heap里面没有元素的时候,会抛出一个IndexError异常,再然后堆栈回滚,再然后lock.release()根本不会执行,这个锁就永远得不到释放,因此就发生了喜闻乐见的死锁问题。这个也是很多大神们讨厌异常的原因。经典Java风格的解决方案就是

 

Python是一种脚本语言,因为有丰富的Python库,从而是Python的功能非常强大,你可以参考 http://baike.baidu.com/view/21087.htm

Python,是一种面向对象的解释型计算机程序设计语言,具有丰富和强大的库,Python 已经成为继Java,C++之后的的第三大语言。特点:简单易学、免费开源、高层语言、可移植性强、面向对象、可扩展性

lock = threading.Lock()...lock.acquire()try: elem = heapq.heappop(heap)finally: lock.release()

这个虽然可以,但是怎么看怎么dirty,和Python优雅、简单的风格出入很大。其实,自从Python2.5开始引入了with语句,一切就变得非常简单:

 

Python是一种脚本语言,因为有丰富的Python库,从而是Python的功能非常强大,你可以参考 http://baike.baidu.com/view/21087.htm

Python,是一种面向对象的解释型计算机程序设计语言,具有丰富和强大的库,Python 已经成为继Java,C++之后的的第三大语言。特点:简单易学、免费开源、高层语言、可移植性强、面向对象、可扩展性

lock = threading.Lock()...with lock: elem = heapq.heappop(heap)

在此无论以何种方式离开with语句的代码块,锁都会被释放。

with语句的设计目的就是为了使得之前需要通过try...finally解决的清理资源问题变得简单、清晰,它的的用法是

 

Python是一种脚本语言,因为有丰富的Python库,从而是Python的功能非常强大,你可以参考 http://baike.baidu.com/view/21087.htm

Python,是一种面向对象的解释型计算机程序设计语言,具有丰富和强大的库,Python 已经成为继Java,C++之后的的第三大语言。特点:简单易学、免费开源、高层语言、可移植性强、面向对象、可扩展性

with expression [as variable]: with-block

其中expression返回一个叫做「context manager」的对象,然后这个对象被赋给variable(如果有的话)。「context manager」对象有两个方法,分别是__enter__()和__exit__(),很明显一个在进入with-block时调用,一个离开with-block的时候调用。

这样的对象不需要自己去实现,在Python标准库里面很多API都是已经实现了这两个方法,最常见的一个例子就是读写文件的open语句。

 

Python是一种脚本语言,因为有丰富的Python库,从而是Python的功能非常强大,你可以参考 http://baike.baidu.com/view/21087.htm

Python,是一种面向对象的解释型计算机程序设计语言,具有丰富和强大的库,Python 已经成为继Java,C++之后的的第三大语言。特点:简单易学、免费开源、高层语言、可移植性强、面向对象、可扩展性

with open('1.txt', encoding = 'utf-8') as fp: lines = fp.readlines()

无论是正常离开还是因为异常原因离开with语句块,打开的文件资源总是会释放。

接下去讨论一下with语句配合contextlib库的一些比较实用的方法,比如需要同时打开两个文件,一个读一个写,这个时候就可以这样写:

 

Python是一种脚本语言,因为有丰富的Python库,从而是Python的功能非常强大,你可以参考 http://baike.baidu.com/view/21087.htm

Python,是一种面向对象的解释型计算机程序设计语言,具有丰富和强大的库,Python 已经成为继Java,C++之后的的第三大语言。特点:简单易学、免费开源、高层语言、可移植性强、面向对象、可扩展性

from contextlib import nested...with nested(open('in.txt'), open('out.txt', 'w')) as (fp_in, fp_out): ...

这样就可以省掉两个with的语句的嵌套了,另外如果遇到一些还没有支持「context manager」的API呢?比如urllib.request.urlopen(),这个返回的对象因为不是「context manager」,结束的时候还需要自己去调用close方法。

类似这种API,contextlib提供了一个叫做closing方法,它会在离开with语句的时候,自动调用对象的close方法,因此urlopen也可以这样写:

 

Python是一种脚本语言,因为有丰富的Python库,从而是Python的功能非常强大,你可以参考 http://baike.baidu.com/view/21087.htm

Python,是一种面向对象的解释型计算机程序设计语言,具有丰富和强大的库,Python 已经成为继Java,C++之后的的第三大语言。特点:简单易学、免费开源、高层语言、可移植性强、面向对象、可扩展性

from contextlib import closing...with closing(urllib.request.urlopen('http://www.yahoo.com')) as f: for line in f: sys.stdout.write(line)

python 里面分为 基本数据类型 和 复合数据类型基本数据类型包括:数值 字符串 布尔 和 none复合数据类型包括:列表 元组 字典 和集合内容来自www.zgxue.com请勿采集。

免责声明 - 关于我们 - 联系我们 - 广告联系 - 友情链接 - 帮助中心 - 频道导航
Copyright © 2017 www.zgxue.com All Rights Reserved