2023年11月29日发(作者:)

详解Pythoncontextlib上下⽂管理模块的⽤法

咱们⽤的os模块,读取⽂件的时候,其实他是含有__enter__ __exit__ ⼀个是with触发的时候,⼀个是退出的时候。

with file('nima,'r') as f:

print ne()

那咱们⾃⼰再实现⼀个标准的可以with的类。 我个⼈写python的时候,喜欢针对⼀些需要有关闭逻辑的代码,构造成with的模

#encoding:utf-8

class echo:

def __enter__(self):

print 'enter'

def __exit__(self,*args):

print 'exit'

with echo() as e:

print 'nima'

contextlib是个⽐with优美的东西,也是提供上下⽂机制的模块,它是通过Generator装饰器实现的,不再是采⽤__enter__

__exit__contextlib中的contextmanager作为装饰器来提供⼀种针对函数级别的上下⽂管理机制。

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

我这⾥再贴下我上次写的redis分布式锁代码中有关于contextlib的⽤法。其实乍⼀看,⽤了withcontextlib⿇烦了,但是最少

让你的主体代码更加鲜明了。

from contextlib import contextmanager

from random import random

DEFAULT_EXPIRES = 15

DEFAULT_RETRIES = 5

@contextmanager

def dist_lock(key, client):

key = 'lock_%s' % key

Context Manager API

⼀个上下⽂管理器通过with声明激活, ⽽且API包含两个⽅法。__enter__()⽅法运⾏执⾏流进⼊到with代码块内。他返回⼀个对

象共上下⽂使⽤。当执⾏流离开with块时,__exit__()⽅法上下⽂管理器清除任何资源被使⽤。

class Context(object):

def __init__(self):

print '__init__()'

def __enter__(self):

print '__enter__()'

return self

def __exit__(self, exc_type, exc_val, exc_tb):

print '__exit__()'

with Context():

print 'Doing work in the context.'

打印结果

__init__()

__enter__()

Doing work in the context.

__exit__()

执⾏上下⽂管理器时会调⽤__enter__离开时调⽤__exit__

__enter__能返回任意对象,联合⼀个指定名字于with声明。

class WithinContext(object):

def __init__(self, context):

print 'WithinContext.__init__(%s)' % context

def do_something(self):

print '_something()'

def __del__(self):

print 'WithinContext.__del__'

class Context(object):

def __init__(self):

class Context(object):

def __init__(self, handle_error):

print '__init__(%s)' % handle_error

_error = handle_error

def __enter__(self):

print '__enter__()'

return self

def __exit__(self, exc_type, exc_val, exc_tb):

print '__exit__(%s, %s, %s)' % (exc_type, exc_val, exc_tb)

return _error

Normal:

entering

inside with statement: {}

exiting

handled ereor:

entering

Error: show example of handling an error

exiting

unhandled error:

entering

exiting

Traceback (most recent call last):

File "", line 30, in

raise ValueError('this exception is not handled')

ValueError: this exception is not handled

嵌套上下⽂

使⽤nested()可以同时管理多个上下⽂。

print 'Normal Example:'