[Tutor] reading lines from a list of files
Oscar Benjamin
oscar.j.benjamin at gmail.com
Tue May 12 17:42:47 CEST 2015
On 12 May 2015 at 11:46, Peter Otten <__peter__ at web.de> wrote:
>
> > although the reason
> > for my inquiry was more to diminish levels of indentation
> > than number of lines.
>
> You usually do that by factoring out the loops into a generator:
>
> def lines(files):
> for file in files:
> with open(files) as f:
> yield from f # before python 3.3: for line in f: yield line
>
>
> for line in lines(files):
> ...
>
>
> Also possible, but sloppy as files are closed on garbage collection rather
> than explicitly:
>
> lines = (line for file in files for line in open(file))
> for line in lines:
> ...
The lines generator function above relies on __del__ as well if the
loop exits from break, return or an exception in the loop body. This
happens whenever you yield or yield-from from inside a with block. The
chain of events that calls your context manager if I break from the
loop is:
1) Once the for loop discards the generator it has a zero reference count.
2) generator.__del__() called.
3) __del__() calls close()
4) close() throws GeneratorExit into the generator frame.
5) The GeneratorExit triggers the __exit__() methods of any context
managers active in the generator frame.
Try the following:
$ cat test_gen_cm.py
#!/usr/bin/env python3
class cleanup():
def __enter__(self):
pass
def __exit__(self, *args):
print("__exit__ called")__del__.
def generator_with_cm():
with cleanup():
yield 1
yield 2
yield 3
g = generator_with_cm()
for x in g:
break
print('Deleting g')
del g
print('g is now deleted')
$ ./test_gen_cm.py
Deleting g
__exit__ called
g is now deleted
A generator cannot guarantee that execution continues after a yield so
any context manager used around a yield is dependent on __del__. I
think a good rule of thumb is "don't yield from a with block".
Alex I apologise if what I've written here is confusing but really
what you started with is just fine. It is not important to fully
understand what I wrote above.
--
Oscar
More information about the Tutor
mailing list