Python with与 contextlib

hosts = file('D:/Test.txt')
try:
    for line in hosts:
        if line.startswith('#'):
            continue
        print line
finally:
    hosts.close()

 

with:可不关闭,与C#中using 类似:

with file('D:/Test.txt') as hosts:
    for line in hosts:
        if line.startswith('#'):
            continue
        print host

 

要使用with,需要类实现 __enter__ 与 __exit__ 方法

 

class Context(object):
    def __enter__(self):
        print 'Starting'
    def __exit__(self, exception_type, exception_value, exception_traceback):
        print 'Leaving'
        if exception_type is None:
            print 'with no Error'
        else:
            print 'with an error (%s)' % exception_value
           
with Context():
    print 'i am the zone'

结果>>> Starting
i am the zone
Leaving
with no Error

 

contextlib 模块 为with提供辅助类

from contextlib import  contextmanager
'''增强了包含yield语句 分开 __enter__ 和 __exit__'''
@contextmanager
def context():
    print 'entering the zone'
    try:       
        yield
    except Exception, e:
        print 'with an error (%s)' % e
        raise e
    else:
        print 'with no error'

with context():
    print 'i am the zone'

 


上下文实例

# -*- coding: utf-8 -*-
import logging
from contextlib import contextmanager

@contextmanager
def logged(klass, logger):
    #记录器
    def _log(f):
        def __log(*args, **kw):
            logger(f, args, kw)
            return f(*args, **kw)
        return __log
   
    #装备类
    for attribute in dir(klass):
        if attribute.startswith('_'):
            continue
        element = getattr(klass, attribute)
        setattr(klass, '__logged_%s' % attribute, element)
        setattr(klass, attribute, _log(element))
   
    #正常工作
    yield klass
   
    #移除日志
    for attribute in dir(klass):
        if not attribute.startswith('__loged_'):
            continue
        element = getattr(klass, attribute)
        setattr(klass, attribute[len('__logged_'):], element)
        delattr(klass, attribute)


class One(object):
    def _private(self):
        pass
    def one(self, other):
        self.two()
        other.thing(self)
        self._private()
    def two(self):
        pass

class Two(object):
    def thing(self, other):
        other.two()

calls = []
def called(meth, args, kw):
    calls.append(meth.im_func.func_name)
   
with logged(One, called):
    one = One()
    two = Two()
    one.one(two)

print calls

>>> ['one', 'two', 'two']

 

 

 
posted @ 2012-04-19 11:42  谷安  阅读(561)  评论(0编辑  收藏  举报