Python: Why are there extra blank lines in the output when using write()?

2.8k views Asked by At

Please consider the following Python 3.x code:

class FancyWriter:    
    def write(self, string):
        print('<'+string+'>')
        return len(string)+2

def testFancyWriter():
    fw = FancyWriter()
    print("Hello World!", file=fw)
    print("How many new lines do you see here?", file=fw)
    print("And here?", file=fw)
    return

testFancyWriter()

The output looks like the following:

<Hello World!>
<
>
<How many new lines do you see here?>
<
>
<And here?>
<
>

Why are these blank lines in between?

OK - the real intention for creating something like a FancyWriter class was actually to create a writer class for Excel: I need to write out tabbed text lines into Excel cells, each line in an Excel row, and each tab-separated substring into the cells of that row. Strange thing is that in that ExcelWriter class (which has also a write() function like above, just that the call to print() is replaced by setting the cells value), a similar phenomenon occurs - there are blank rows like in the FancyWriter classes' output above! (I have the target cell moving one row below, if the last character of the incoming string was a '\n'.)

Would someone be able to explain this? What is actually happening between the lines, in a literal sense?

And what would be the 'most pythonic way' for a FancyWriter (output? file?) class with a write function to get the desired output like

<Hello World!>
<How many new lines do you see here?>
<And here?>

Thanks a lot in advance!

1

There are 1 answers

4
DSM On

Your "blank lines" are really your function being called with a string '\n', to handle the end of line. For example, if we change the print to

print(repr(string))

and change the hello world line to

print("Hello World!", file=fw, end="zzz")

we see

'Hello World!'
'zzz'
'How many new lines do you see here?'
'\n'
'And here?'
'\n'

Basically, print doesn't build a string and then add the end value to it, it simply passes end to the writer itself.

If you want to avoid this, you'll have to avoid print, I think, or special-case your writer to handle the case of receiving a certain (say, empty) argument, because it looks like print is going to pass end even if it's the empty string.