On 23 May 2015 at 10:52, Peter Otten <__pete...@web.de> wrote:
> import csv
>
>

I'm just wondering what other people think about this. Should code
like make_lines below be discouraged?

> def make_lines():
>     with open('co2-sample.csv') as co2:
>         yield htbegin
>         for linelist in csv.reader(co2):
>             yield from fprint(linelist)
>         yield htend
>
>
> def fprint(linelist):
>     yield ("<td class=l>{}</td><td>{}</td><td>{}</td>"
>            "<td>{}</td><td>{}</td><td>{}</td>\n").format(*linelist)
>     yield '</tr>\n'

There's a fundamental contradiction between the with and yield
statements. With means "don't exit this block without running my
finalisation routine". Yield means "immediately exit this block
without doing anything (including any finalisation routines) and then
allow anything else to occur".

Using yield inside a with statement like this renders the with
statement pointless: either way we're really depending on __del__ to
execute the finalisation code. So it with or without the with
statement it will work fine on CPython. On other implementations it
may or may not close the file with or without the with statement. IOW
the with statement is not able to provide the guarantees normally
expected of it when used this way.

It's usually fairly trivial to rearrange things so that this doesn't happen:

def wrap_header_footer(fin):
    yield htbegin
    for linelist in csv.reader(fin):
        yield from fprint(linelist)
    yield htend


--
Oscar
_______________________________________________
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor

Reply via email to