S
Steven D'Aprano
I'm not greatly experienced with context managers and the with statement, so
I would like to check my logic.
Somebody (doesn't matter who, or where) stated that they frequently use this
idiom:
spam = MyContextManager(*args)
for ham in my_iter:
with spam:
# do stuff
but to me that looks badly wrong. Surely the spam context manager object
will exit after the first iteration, and always raise an exception on the
second? But I don't quite understand context managers enough to be sure.
I've tested it with two examples:
# Simple example using built-in file context manager.
.... with spam:
.... print ham
....
0
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
ValueError: I/O operation on closed file
# Slightly more complex example.
.... with spam as page:
.... print ham, sum(len(line) for line in page)
....
0 18486
1
Traceback (most recent call last):
File "<stdin>", line 3, in <module>
File "<stdin>", line 3, in <genexpr>
File "/usr/local/lib/python2.7/socket.py", line 528, in next
line = self.readline()
File "/usr/local/lib/python2.7/socket.py", line 424, in readline
recv = self._sock.recv
AttributeError: 'NoneType' object has no attribute 'recv'
Am I right to expect that the above idiom cannot work? If not, what sort of
context managers do work as shown?
I would like to check my logic.
Somebody (doesn't matter who, or where) stated that they frequently use this
idiom:
spam = MyContextManager(*args)
for ham in my_iter:
with spam:
# do stuff
but to me that looks badly wrong. Surely the spam context manager object
will exit after the first iteration, and always raise an exception on the
second? But I don't quite understand context managers enough to be sure.
I've tested it with two examples:
# Simple example using built-in file context manager.
.... with spam:
.... print ham
....
0
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
ValueError: I/O operation on closed file
# Slightly more complex example.
.... with spam as page:
.... print ham, sum(len(line) for line in page)
....
0 18486
1
Traceback (most recent call last):
File "<stdin>", line 3, in <module>
File "<stdin>", line 3, in <genexpr>
File "/usr/local/lib/python2.7/socket.py", line 528, in next
line = self.readline()
File "/usr/local/lib/python2.7/socket.py", line 424, in readline
recv = self._sock.recv
AttributeError: 'NoneType' object has no attribute 'recv'
Am I right to expect that the above idiom cannot work? If not, what sort of
context managers do work as shown?