3

I thought this should work:

file = open('filename.ppm', 'wb')
file.write('upper\nlower'.encode(encoding='ascii'))

When I run the code, though there is no linebreak; the filename.pmm contains 'upperlower' when opened with notepad.

snakecharmerb
  • 47,570
  • 11
  • 100
  • 153
kuco 23
  • 786
  • 5
  • 18
  • There is nothing, it reads upperlower. I open the file with notepad after the code runs. – kuco 23 Sep 22 '19 at 20:36
  • can you drop the encode part? This should be the right way to do it despite that: https://stackoverflow.com/questions/2918362/writing-string-to-a-file-on-a-new-line-every-time –  Sep 22 '19 at 20:37
  • It gives a TypeError saying a bytes object is required. – kuco 23 Sep 22 '19 at 20:39

3 Answers3

6

Specify the encoding in open():

>>> with open("filename.ppm", "w", encoding="ascii") as f:
...     f.write("upper\nlower")

$ cat filename.ppm
upper
lower $

The documentation for the open() function may have several clues as to why your current method gives you something you didn't expect.

Firstly, regarding the newline and \n versus \r\n:

When writing output to the stream, if newline is None, any '\n' characters written are translated to the system default line separator, os.linesep. If newline is '' or '\n', no translation takes place. If newline is any of the other legal values, any '\n' characters written are translated to the given string.

My guess is that, in your case, because you're writing bytes to the output stream, that translation may not occur as the 'raw' bytes are written to file.

One last thing worth mentioning is the use of encoding="ascii". In this case, that shouldn't actually matter, because ASCII is a subset of Unicode, and all of your characters fall in the ASCII range.

>>> all(i.isascii() for i in "upper\nlower")
True
Brad Solomon
  • 38,521
  • 31
  • 149
  • 235
2

When you write to a file in binary mode ('wb'), Python writes exactly the bytes that you provide. Thus, if you write 'foo\nbar', that is what gets written to disk - even if '\n' is not recognised as a newline marker on the platform running your code.

If you write to a file in text mode ('w'), Python will convert '\n' to the appropriate newline marker for the platform running the code, as long as you don't set the newline parameter:

When writing output to the stream, if newline is None, any '\n' characters written are translated to the system default line separator, os.linesep. If newline is '' or '\n', no translation takes place. If newline is any of the other legal values, any '\n' characters written are translated to the given string.

snakecharmerb
  • 47,570
  • 11
  • 100
  • 153
1

Windows uses \r\n to represent a new line whereas Linux just uses \n. Add the \r carriage return to see the line breaks in notepad.

file.write('upper\r\nlower')
Mikey Lockwood
  • 1,258
  • 1
  • 9
  • 22