关于python:将行写入文件的正确方法?

Correct way to write line to file?

我习惯了做print >>f,"hi there"

然而,似乎print >>正受到抨击。上面这一行的推荐方法是什么?

更新:关于所有关于"
"
的答案…这是通用的还是特定于Unix的?我应该在窗户上做"

"吗?


您应该使用自python 2.6以来可用的print()函数。+

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

对于python 3,您不需要import,因为print()函数是默认的。

另一种选择是使用:

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

引用python文档中有关换行的内容:

On output, if newline is None, any '
'
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 '
'
characters written are translated to the given string.


这应该简单到:

1
2
3
with open('somefile.txt', 'a') as the_file:
    the_file.write('Hello
'
)

从文档中:

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

一些有用的读物:

  • with声明
  • open()
    • "a"用于追加或使用
    • "w"以截断方式写入
  • os(特别是os.linesep)


python文档建议这样做:

1
2
with open('file_to_write', 'w') as f:
    f.write('file contents')

所以我通常是这样做的:)

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.


关于os.linesep:

下面是一个未经编辑的精确的Windows python 2.7.1解释器会话:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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
'

'

>>> f = open('myfile','w')
>>> f.write('hi there
'
)
>>> f.write('hi there' + os.linesep) # same result as previous line ?????????
>>> f.close()
>>> open('myfile', 'rb').read()
'hi there

hi there


'

>>>

在Windows上:

正如预期的那样,os.linesep不会产生与'
'
相同的结果。它不可能产生同样的结果。'hi there' + os.linesep相当于'hi there

',不相当于'hi there
'

这很简单:使用
,它将自动转换为os.linesep。自从第一个从Python到Windows的端口以来,它就这么简单了。

在非Windows系统上使用os.linesep没有意义,它会在Windows上产生错误的结果。

不要使用os.linesep!


我认为没有"正确"的方法。

我会用:

1
2
with open ('myfile', 'a') as f: f.write ('hi there
'
)

为了纪念蒂姆·托迪。


在python 3中,它是一个函数,但是在python 2中,您可以将其添加到源文件的顶部:

1
from __future__ import print_function

然后你这样做

1
print("hi there", file=f)


如果你写了大量的数据,速度是一个问题,你可能应该使用f.write(...)。我做了一个快速的速度比较,它比执行大量写入时的print(..., file=f)快得多。

1
2
3
4
5
6
7
8
9
10
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
')
end = time.time()
print(end - start)

在我的机器上,write平均完成时间为2.45秒,而print的完成时间约为9.76秒的4倍。也就是说,在大多数现实场景中,这不会是一个问题。

如果你选择和print(..., file=f)一起去,你可能会发现你会不时地想要压制新行,或者用别的东西来代替新行。这可以通过设置可选的end参数来实现,例如:

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

无论您选择哪种方式,我都建议使用with,因为它使代码更容易阅读。

更新:这种性能上的差异是由这样一个事实来解释的:write是高度缓冲的,在任何写入磁盘之前都会返回(见这个答案),而print可能使用行缓冲。对此的一个简单测试是检查长时间写入的性能,在这种情况下,行缓冲的缺点(在速度方面)将不那么明显。

1
2
3
4
5
6
7
8
9
10
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 + '
')
end = time.time()

print(end - start,"s")

性能差异现在变得更加不明显,write的平均时间为2.20秒,print的平均时间为3.10秒。如果需要连接一组字符串以获得这种looong行性能,那么使用print效率更高的用例就比较少见了。


因为3.5,您也可以使用pathlib:

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

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

1
2
3
import pathlib

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

当您说行时,它意味着一些序列化字符结束于'字符。行应该在某个点最后,所以我们应该在每行的末尾考虑''。以下是解决方案:

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

在每次写入后的附加模式下,光标移动到新行,如果要使用"w"模式,应在write()函数的末尾添加'字符:

1
2
the_file.write('Hello'+'
'
)


也可以使用io模块,如下所示:

1
2
3
4
5
import io
my_string ="hi there"

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