使用比with更优雅的contextlib实现上下文

前几天发现了一个优化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-8class 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@contextmanagerdef 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 contextmanagerfrom random import randomDEFAULT_EXPIRES = 15DEFAULT_RETRIES = 5@contextmanagerdef 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都是随你的便的,如果想提高你的逼格,倒是真的可以试试。

使用比with更优雅的contextlib实现上下文

相关文章:

你感兴趣的文章:

标签云: