python中关于with及contextlib的用法

平常Coding过程中,经常使用到的with场景是(打开文件进行文件处理,然后隐式地执行了文件句柄的关闭,同样适合socket之类的,这些类都提供了对with的支持):


1

2

with file(‘test.py‘,‘r‘) as f :

    print f.readline()

with的作用,类似try...finally...,提供一种上下文机制,要应用with语句的类,其内部必须提供两个内置函数__enter__以及__exit__。前者在主体代码执行前执行,后则在主体代码执行后执行。as后面的变量,是在__enter__函数中返回的。通过下面这个代码片段以及注释说明,可以清晰明白__enter__与__exit__的用法:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

#!encoding:utf-8

class echo :

    def output(self) :

        print ‘hello world‘

    def __enter__(self):

        print ‘enter‘

        return self #返回自身实例,当然也可以返回任何希望返回的东西

    def __exit__(self, exception_type, exception_value, exception_traceback):

        #若发生异常,会在这里捕捉到,可以进行异常处理

        print ‘exit‘

        #如果改__exit__可以处理改异常则通过返回True告知该异常不必传播,否则返回False

        if exception_type == ValueError :

            return True

        else:

            return False

 

with echo() as e:

    e.output()

    print ‘do something inside‘

print ‘-----------‘

with echo() as e:

    raise ValueError(‘value error‘)

print ‘-----------‘

with echo() as e:

    raise Exception(‘can not detect‘)

运行结果:

contextlib是为了加强with语句,提供上下文机制的模块,它是通过Generator实现的。通过定义类以及写__enter__和__exit__来进行上下文管理虽然不难,但是很繁琐。contextlib中的contextmanager作为装饰器来提供一种针对函数级别的上下文管理机制。常用框架如下:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

from contextlib import contextmanager

 

@contextmanager

def make_context() :

    print ‘enter‘

    try :

        yield {}

    except RuntimeError, err :

        print ‘error‘ , err

    finally :

        print ‘exit‘

 

with make_context() as value :

    print value

contextlib还有连个重要的东西,一个是nested,一个是closing,前者用于创建嵌套的上下文,后则用于帮你执行定义好的close函数。但是nested已经过时了,因为with已经可以通过多个上下文的直接嵌套了。下面是一个例子:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

from contextlib import contextmanager

from contextlib import nested

from contextlib import closing

@contextmanager

def make_context(name) :

    print ‘enter‘, name

    yield name

    print ‘exit‘, name

 

with nested(make_context(‘A‘), make_context(‘B‘)) as (a, b) :

    print a

    print b

 

with make_context(‘A‘) as a, make_context(‘B‘) as b :

    print a

    print b

 

class Door(object) :

    def open(self) :

        print ‘Door is opened‘

    def close(self) :

        print ‘Door is closed‘

 

with closing(Door()) as door :

    door.open()

运行结果:

总结:python有很多强大的特性,由于我们平常总习惯于之前C++或java的一些编程习惯,时常忽略这些好的机制。因此,要学会使用这些python特性,让我们写的python程序更像是python。

时间: 2024-11-05 12:07:39

python中关于with及contextlib的用法的相关文章

python 中 sorted() 和 list.sort() 的用法

今天用python自带的sorted对一个列表进行排序, 在这里总结一下 只要是可迭代对象都可以用sorted . sorted(itrearble, cmp=None, key=None, reverse=False) =号后面是默认值 默认是升序排序的, 如果想让结果降序排列,用reverse=True 最后会将排序的结果放到一个新的列表中, 而不是对iterable本身进行修改. eg: 1, 简单排序 sorted('123456')  字符串 ['1', '2', '3', '4',

python中List的sort方法的用法

python列表排序 简单记一下python中List的sort方法(或者sorted内建函数)的用法. 关键字: python列表排序 python字典排序 sorted List的元素可以是各种东西,字符串,字典,自己定义的类等. sorted函数用法如下: Python代码   sorted(data, cmp=None, key=None, reverse=False) 其中,data是待排序数据,可以使List或者iterator, cmp和key都是函数,这两个函数作用与data的元

无意学会了python中and和or的有趣用法

今天看书,无意中看到了Python的and和or的一个有趣用法,最后在网上查找这种用法的机制,归根结底还是要仔细理解python中and和or的机制. Python中if-else有多种写法.假设a=10,b=20,取较大者. 最常规的方法是: if a > b:     c = a else:     c = b 稍微高级一点的用法就是用表达式 c = a if a > b else b 我就是经常用这种方法. 再高级一点的用法就是用二维列表 c = [a,b][a<b] 这方法也很好

python中数组与多维数组用法介绍

增加时a.append( 'a ')就可以了.只要按顺序加,就没有问题 . 使用时,完全可以使用下标: 代码如下 复制代码 a[0] a[1] 但出果引用不存在的下标,则会引发异常.这时,你需要先添加元素,再引用就没有问题 了.如果想预先保留空间,可以使用循环来给list,每个元素一个缺省值,再引用就不会有问题 了. 如: 代码如下 复制代码 a=[] for i in range(100): a.append([]) for j in range(100): a[i].append(0) 这样

python中format函数格式化字符串的用法

转载自: http://www.jb51.net/article/105933.htm 前言 Python 在 2.6 版本中新加了一个字符串格式化方法: str.format() .它的基本语法是通过 {} 和 : 来代替以前的 %.. 格式化时的占位符语法: ? 1 replacement_field ::= "{" [field_name] ["!" conversion] [":" format_spec] "}" &

python中常见错误及try-except 的用法

1.常见的错误 我们在使用python过程中会出现: (1)SyntaxError 句法错误. (2)IndentationError 缩进错误. (3)NameError 变量未定义错误. (4)TypeError 类型错误. 2.处理异常 我们使用try...except 来处理异常: 基本语法: try: segment except: segment 首先执行try子句,如果没有异常发生,except 子句不执行.如果执行try子句发生异常,那么该子句就会被忽略,如果异常匹配与 exce

Python中strip()、lstrip()、rstrip()用法详解

Python中有三个去除头尾字符.空白符的函数,它们依次为: strip: 用来去除头尾字符.空白符(包括\n.\r.\t.' ',即:换行.回车.制表符.空格)lstrip:用来去除开头字符.空白符(包括\n.\r.\t.' ',即:换行.回车.制表符.空格)rstrip:用来去除结尾字符.空白符(包括\n.\r.\t.' ',即:换行.回车.制表符.空格) 注意:这些函数都只会删除头和尾的字符,中间的不会删除. 用法分别为:string.strip([chars])string.lstrip

python中split()函数的用法

函数:split() Python中有split()和os.path.split()两个函数,具体作用如下:split():拆分字符串.通过指定分隔符对字符串进行切片,并返回分割后的字符串列表(list)os.path.split():按照路径将文件名和路径分割开 一.函数说明 1.split()函数语法:str.split(str="",num=string.count(str))[n] 参数说明:str:表示为分隔符,默认为空格,但是不能为空('').若字符串中没有分隔符,则把整个

python中logging模块的一些简单用法

用Python写代码的时候,在想看的地方写个print xx 就能在控制台上显示打印信息,这样子就能知道它是什么了,但是当我需要看大量的地方或者在一个文件中查看的时候,这时候print就不大方便了,所以Python引入了logging模块来记录我想要的信息.print也可以输入日志,logging相对print来说更好控制输出在哪个地方,怎么输出及控制消息级别来过滤掉那些不需要的信息. 1.日志级别 import logging # 引入logging模块 # 将信息打印到控制台上 loggin