with
statement¶f = open("a.txt", "w")
f.write("hello")
f.close()
with open("a.txt", "w") as f:
f.write("hello")
f = open("a.txt")
dir(f)
['__class__', '__delattr__', '__doc__', '__enter__', '__exit__', '__format__', '__getattribute__', '__hash__', '__init__', '__iter__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'close', 'closed', 'encoding', 'errors', 'fileno', 'flush', 'isatty', 'mode', 'name', 'newlines', 'next', 'read', 'readinto', 'readline', 'readlines', 'seek', 'softspace', 'tell', 'truncate', 'write', 'writelines', 'xreadlines']
import os
class chdir:
def __init__(self, dir):
self.dir = dir
print "__init__"
def __enter__(self):
print "__enter__"
self.olddir = os.getcwd()
os.chdir(self.dir)
return self
def __exit__(self, *a):
print "__exit__"
os.chdir(self.olddir)
print os.getcwd()
print "before with"
with chdir("/tmp") as x:
print os.getcwd()
print "after with"
print os.getcwd()
/Users/anand/Dropbox/Trainings/2013/advancedpython-may2013 before with __init__ __enter__ /private/tmp __exit__ after with /Users/anand/Dropbox/Trainings/2013/advancedpython-may2013
Problem Write a context manager capture_output
to capture stdout inside a with block.
with capture_output() as buf:
print "hello"
out = buf.getvalue()
print "captured", repr(out)
Hint: See StringIO.StringIO
and sys.stdout
.
Lets try to understand how to capture output without context managers.
import sys
from StringIO import StringIO
oldstdout = sys.stdout
buf = StringIO()
sys.stdout = buf
print "hello"
print "world"
sys.stdout = oldstdout
print "captured", repr(buf.getvalue())
captured 'hello\nworld\n'
# solution
from StringIO import StringIO
import sys
class capture_output:
def __init__(self):
self.buf = StringIO()
def __enter__(self):
self.oldstdout = sys.stdout
sys.stdout = self.buf
return self.buf
def __exit__(self, type, exc, traceback):
sys.stdout = self.oldstdout
#with capture_output() as buf:
# print "hello"
capture_output()
print "hello"
#out = buf.getvalue()
#print "captured", repr(out)
hello
class ignore_exception:
def __init__(self):
pass
def __enter__(self):
pass
def __exit__(self, type, exc, traceback):
print type, exc, traceback
return True
with ignore_exception():
print "begin"
raise IOError("fo")
begin <type 'exceptions.IOError'> fo <traceback object at 0x102f48998>
Problem Improve the above ignore_exception
class to ignore only one particular exception.
with ignore_exception(IOError):
raise IOError("foo")