前几天发现了一个优化with的模块contextlib,其实就是个封装。 那么首先说下,with是什么,玩python有半年经验的应该知道的。 这东西其实也没有什么太大的用处,只是隐藏的含有了一个关闭的逻辑,很像是try…finally…
这里标记下,原文链接是 xiaorui.cc
咱们用的os模块,读取文件的时候,其实他是含有__enter__ __exit__ 。 一个是with触发的时候,一个是退出的时候。
with file('nima,'r') as f: print f.readline()
那咱们自己再实现一个标准的可以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的用法。其实乍一看,用了with和contextlib麻烦了,但是最少让你的主体代码更加鲜明了。
from contextlib import contextmanager from random import random DEFAULT_EXPIRES = 15 DEFAULT_RETRIES = 5 @contextmanager def dist_lock(key, client): key = 'lock_%s' % key try: _acquire_lock(key, client) yield finally: _release_lock(key, client) def _acquire_lock(key, client): for i in xrange(0, DEFAULT_RETRIES): get_stored = client.get(key) if get_stored: sleep_time = (((i+1)*random()) + 2**i) / 2.5 print 'Sleeipng for %s' % (sleep_time) time.sleep(sleep_time) else: stored = client.set(key, 1) client.expire(key,DEFAULT_EXPIRES) return raise Exception('Could not acquire lock for %s' % key) def _release_lock(key, client): client.delete(key)
用不用with或者是contextlib都是随你的便的,如果想提高你的逼格,倒是真的可以试试。
这个分布式锁有问题嘛?get_stored = client.get(key) 的时候返回false,此后别的进程stored = client.set(key, 1)了,是会出错吗?
赞
楼主好巧 我自己写经常写nima
哈哈,是呀 同道中人
不错不错