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']