Correct way to write line to file?

Correct way to write line to file?

https://stackoverflow.com/questions/6159900/correct-way-to-write-line-to-file

I'm used to doing print >>f, "hi there"

However, it seems that print >> is getting deprecated. What is the recommended way to do the line above?

Update: Regarding all those answers with "\n"...is this universal or Unix-specific? IE, should I be doing "\r\n" on Windows?

python file-io

share improve this question

edited Nov 13 '17 at 0:44

 

martineau

86.1k1717 gold badges117117 silver badges220220 bronze badges

asked May 28 '11 at 5:44

 

Yaroslav Bulatov

50k1717 gold badges115115 silver badges170170 bronze badges

  • 11

    "\n" is not Unix-specific. When the file is opened in text mode (the default), it is translated automatically to the correct line ending for the current platform. Writing "\r\n" would produce "\r\r\n" which is wrong. – D Coetzee Nov 2 '13 at 17:39

  • Just add the print ord(os.linesep) statement to see the ascii code (10 on most UNIX systems) – Stefan Gruenwald Mar 20 '17 at 17:08

  • Why do you think it is deprecated? – xxx--- Jun 15 '19 at 7:32

add a comment

13 Answers

Active Oldest Votes

1144

This should be as simple as:

with open('somefile.txt', 'a') as the_file:
    the_file.write('Hello\n')

From The Documentation:

Do not use os.linesep as a line terminator when writing files opened in text mode (the default); use a single '\n' instead, on all platforms.

Some useful reading:

share improve this answer

edited Oct 11 '17 at 10:46

 

Jason

5,17622 gold badges2727 silver badges3333 bronze badges

answered May 28 '11 at 6:36

 

Johnsyweb

112k2020 gold badges160160 silver badges219219 bronze badges

  • 36

    This example is better than the open/close example. Using with is a safer way to remember to close a file. – Eyal Feb 8 '14 at 5:11

  • 18

    I don't have to call the_file.close() ? – Hussain Jun 5 '14 at 15:26

  • 19

    no you don't: stackoverflow.com/questions/3012488/… – Tal Jerome Oct 6 '14 at 7:54

  • @Johnsyweb Why do you say "os.linesep. There's lots of good stuff in os!", when you've earlier in the post recommended against using it? I'm suspecting an edit here, and it might be the reason for the down votes. – Horse SMith Dec 2 '14 at 19:35

  • 1

    @user3226167: That's an interesting point. But why would you open a binary file to write plain text? – Johnsyweb May 31 '17 at 8:40

show 5 more comments

961

You should use the print() function which is available since Python 2.6+

from __future__ import print_function  # Only needed for Python 2
print("hi there", file=f)

For Python 3 you don't need the import, since the print() function is the default.

The alternative would be to use:

f = open('myfile', 'w')
f.write('hi there\n')  # python will convert \n to os.linesep
f.close()  # you can omit in most cases as the destructor will call it

Quoting from Python documentation regarding newlines:

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

share improve this answer

edited Jan 1 '17 at 21:19

Martin Tournoij

21.5k1717 gold badges8383 silver badges114114 bronze badges

answered May 28 '11 at 5:48

sorin

123k128128 gold badges426426 silver badges649649 bronze badges

  • 35

    -1 "If you want to be sure, add os.linesep to the string instead of \n" would require newline="" otherwise you'd get \r\r\n on Windows. There is no reason to futz about with os.linesep at all. – John Machin May 28 '11 at 7:23

  • 7

    @Sorin: Your edit to add write mode is of course an improvement. However you strangely remain intransigent about os.linesep. See my answer. By the way, the documentation that you quote is for 3.x, but this part is also valid for 2.x in text mode: any '\n' characters written are translated to the system default line separator, os.linesep* ... Windows: writing os.linesep is the same as writing \r\n which contains \n which is translated to os.linesep which is \r\n so the end result is \r\r\n. – John Machin May 29 '11 at 3:16

  •  
  • 7

    @John you were right, I corrected the os.linesep bug. Thanks. – sorin May 29 '11 at 7:24

  • 3

    For appending isnt it open('myfile','a') instead open('myfile','w')? – NeDark Aug 1 '15 at 0:59

  • 6

    @BradRuderman That's part of the POSIX standard for what constitutes a "line" in a text file, i.e. every line in a text file must be terminated by a newline, even the last line. – wheeler Mar 2 '17 at 20:18

show 11 more comments

116

The python docs recommend this way:

with open('file_to_write', 'w') as f:
    f.write('file contents\n')

So this is the way I usually do it :)

Statement from docs.python.org:

It is good practice to use the 'with' keyword when dealing with file objects. This has the advantage that the file is properly closed after its suite finishes, even if an exception is raised on the way. It is also much shorter than writing equivalent try-finally blocks.

share improve this answer

edited Jan 23 at 1:55

dcoles

2,34811 gold badge1616 silver badges1717 bronze badges

answered Oct 13 '12 at 9:37

j7nn7k

14.3k1616 gold badges7272 silver badges8383 bronze badges

  • 1

    I don't like this way when I need to nest the with inside a loop. That makes me constantly open and close the file as I proceed in my loop. Maybe I am missing something here, or this is really a disadvantage in this particular scenario? – Sibbs Gambling Nov 18 '16 at 19:33

  • 38

    How about looping within the with? – j7nn7k Dec 4 '16 at 19:37

  • @j7nn7k for line in fd: – momstouch Jun 19 '19 at 6:18

add a comment

86

Regarding os.linesep:

Here is an exact unedited Python 2.7.1 interpreter session on Windows:

Python 2.7.1 (r271:86832, Nov 27 2010, 18:30:46) [MSC v.1500 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.linesep
'\r\n'
>>> f = open('myfile','w')
>>> f.write('hi there\n')
>>> f.write('hi there' + os.linesep) # same result as previous line ?????????
>>> f.close()
>>> open('myfile', 'rb').read()
'hi there\r\nhi there\r\r\n'
>>>

On Windows:

As expected, os.linesep does NOT produce the same outcome as '\n'. There is no way that it could produce the same outcome. 'hi there' + os.linesep is equivalent to 'hi there\r\n', which is NOT equivalent to 'hi there\n'.

It's this simple: use \n which will be translated automatically to os.linesep. And it's been that simple ever since the first port of Python to Windows.

There is no point in using os.linesep on non-Windows systems, and it produces wrong results on Windows.

DO NOT USE os.linesep!

share improve this answer

answered May 29 '11 at 3:02

John Machin

71k99 gold badges112112 silver badges170170 bronze badges

  • great example -- curious if you're an ipython user? nice functions for formatting sessions – Alvin Sep 12 '12 at 8:22

  • I'm not entirely sure what you are trying to tell us here. os.linesep will return the line term character (or string) as defined by the operating system. Windows uses \r\n for line endings by default. However, a single \n is recognised. Using \n is going to give a fully portable OUTPUT but os.linesep is not wrong on windows. – Gusdor Feb 13 '13 at 12:08

  • 5

    @Gusdor: The point is that if you explicitly use os.linesep in Windows in text mode, the outcome is \r\r\n which is wrong. "Windows uses ..." is meaningless. The C runtime library (and hence Python) translate \n to \r\n on output in text mode. Other software may behave differently. It is NOT the case that all software running on Windows recognises a lone \n as a line separator when reading in text mode. Python does. Microsoft's Notepad text editor doesn't. – John Machin Feb 13 '13 at 20:32

  • 6

    Arguably somebody else will be reading it, not you, with some mickey-mouse software that will barf about the extra \r ... – John Machin Feb 14 '13 at 11:42

  • 2

    @Gusdor are you coming to python from a different language, where using '\n' results in output of '\n' on window, rather than '\r\n' -- so it lacks the '\r' expected by dumb text editors? As John says, that isn't how Python behaves -- '\n' is automatically replaced by '\r\n', if that is what os.linesep says to do. Hence, explicitly saying os.linesep is "wrong" here. Its like Department of Redundancy Department. Yes you can do it. No, you don't want to. – ToolmakerSteve Dec 19 '13 at 3:12

  •  

show 2 more comments

55

I do not think there is a "correct" way.

I would use:

with open ('myfile', 'a') as f: f.write ('hi there\n')

In memoriam Tim Toady.

share improve this answer

edited May 28 '11 at 5:54

answered May 28 '11 at 5:48

 

Hyperboreus

28.4k77 gold badges4040 silver badges7777 bronze badges

  • But the OP might want to write additional stuff to the file. Here the file will be closed when the with goes out of scope. – Keith May 28 '11 at 5:51

  • That might want to be open(..., 'a') or even 'at'. – mtrw May 28 '11 at 5:53

  • 5

    Erm, yeah. That is the idea of using with. If you want to keep the file open, just call open at the beginning and call close when you are done... – Hyperboreus May 28 '11 at 5:53

  • 1

    @mtrw. True. OP was appending. – Hyperboreus May 28 '11 at 5:54

  • 1

    As far as python is concerned is RIP Tim Toady - and very very very rightfully so – Mr_and_Mrs_D Jul 6 '17 at 12:27

show 2 more comments

21

In Python 3 it is a function, but in Python 2 you can add this to the top of the source file:

from __future__ import print_function

Then you do

print("hi there", file=f)

share improve this answer

answered May 28 '11 at 5:49

 

Keith

35.1k99 gold badges4747 silver badges6565 bronze badges

add a comment

17

If you are writing a lot of data and speed is a concern you should probably go with f.write(...). I did a quick speed comparison and it was considerably faster than print(..., file=f) when performing a large number of writes.

import time    

start = start = time.time()
with open("test.txt", 'w') as f:
    for i in range(10000000):
        # print('This is a speed test', file=f)
        # f.write('This is a speed test\n')
end = time.time()
print(end - start)

On average write finished in 2.45s on my machine, whereas print took about 4 times as long (9.76s). That being said, in most real-world scenarios this will not be an issue.

If you choose to go with print(..., file=f) you will probably find that you'll want to suppress the newline from time to time, or replace it with something else. This can be done by setting the optional end parameter, e.g.;

with open("test", 'w') as f:
    print('Foo1,', file=f, end='')
    print('Foo2,', file=f, end='')
    print('Foo3', file=f)

Whichever way you choose I'd suggest using with since it makes the code much easier to read.

Update: This difference in performance is explained by the fact that write is highly buffered and returns before any writes to disk actually take place (see this answer), whereas print (probably) uses line buffering. A simple test for this would be to check performance for long writes as well, where the disadvantages (in terms of speed) for line buffering would be less pronounced.

start = start = time.time()
long_line = 'This is a speed test' * 100
with open("test.txt", 'w') as f:
    for i in range(1000000):
        # print(long_line, file=f)
        # f.write(long_line + '\n')
end = time.time()

print(end - start, "s")

The performance difference now becomes much less pronounced, with an average time of 2.20s for write and 3.10s for print. If you need to concatenate a bunch of strings to get this loooong line performance will suffer, so use-cases where print would be more efficient are a bit rare.

share improve this answer

edited Sep 15 '17 at 9:17

answered Sep 13 '16 at 16:20

 

Robin Keskisarkka

66266 silver badges1313 bronze badges

add a comment

10

Since 3.5 you can also use the pathlib for that purpose:

Path.write_text(data, encoding=None, errors=None)

Open the file pointed to in text mode, write data to it, and close the file:

import pathlib

pathlib.Path('textfile.txt').write_text('content')

share improve this answer

edited Apr 28 at 11:05

 

phoenix

2,85811 gold badge2626 silver badges2828 bronze badges

answered Sep 12 '18 at 7:50

johnson

1,17622 gold badges1212 silver badges1818 bronze badges

add a comment

5

When you said Line it means some serialized characters which are ended to '\n' characters. Line should be last at some point so we should consider '\n' at the end of each line. Here is solution:

with open('YOURFILE.txt', 'a') as the_file:
    the_file.write("Hello")

in append mode after each write the cursor move to new line, if you want to use w mode you should add \n characters at the end of the write() function:

the_file.write("Hello\n")

share improve this answer

edited May 10 at 17:04

 

alper

1,19111 gold badge2121 silver badges3737 bronze badges

answered Aug 26 '16 at 14:44

 

Reza Tanzifi

29433 silver badges1212 bronze badges

  • 1

    "in append mode after each write the cursor move to new line" – no it's not. – An Se Feb 21 '19 at 10:27

add a comment

3

One can also use the io module as in:

import io
my_string = "hi there"

with io.open("output_file.txt", mode='w', encoding='utf-8') as f:
    f.write(my_string)

share improve this answer

answered Aug 29 '18 at 14:37

 

kmario23

31.5k99 gold badges101101 silver badges111111 bronze badges

add a comment

0

You can also try filewriter

pip install filewriter

from filewriter import Writer

Writer(filename='my_file', ext='txt') << ["row 1 hi there", "row 2"]

Writes into my_file.txt

Takes an iterable or an object with __str__ support.

share improve this answer

answered Jun 14 '19 at 8:32

 

Emin Bugra Saral

3,14011 gold badge1313 silver badges2121 bronze badges

add a comment

0

When I need to write new lines a lot, I define a lambda that uses a print function:

out = open(file_name, 'w')
fwl = lambda *x, **y: print(*x, **y, file=out) # FileWriteLine
fwl('Hi')

This approach has the benefit that it can utilize all the features that are available with the print function.

Update: As is mentioned by Georgy in the comment section, it is possible to improve this idea further with the partial function:

from functools import partial
fwl = partial(print, file=out)

IMHO, this is a more functional and less cryptic approach.

share improve this answer

edited Jul 6 '19 at 2:07

answered Jul 5 '19 at 10:36

 

MxNx

1,0691414 silver badges2626 bronze badges

  • 2

    Or another (probably cleaner) way to write this: from functools import partial; fwl = partial(print, file=out). – Georgy Jul 5 '19 at 10:56

  •  
  • @Georgy Your approach is so good that it can be given as a new answer. – MxNx Jul 5 '19 at 11:10

  • 1

    The idea is the same as yours, just implementation is a bit different. If you want, you can add it in an edit to your answer. I'm fine with it. – Georgy Jul 5 '19 at 11:30

add a comment

0

To write text in a file in the flask can be used:

filehandle = open("text.txt", "w")
filebuffer = ["hi","welcome","yes yes welcome"]
filehandle.writelines(filebuffer)
filehandle.close()

share improve this answer

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值