正确的写行到文件的方法?

Yar*_*tov 985 python file-io

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

但是,它似乎print >>已被弃用.建议的方法是什么?

更新:关于所有这些答案"\n"......是通用的还是特定于Unix的?IE,我应该"\r\n"在Windows 上做什么?

Joh*_*web 1016

这应该很简单:

with open('somefile.txt', 'a') as the_file:
    the_file.write('Hello\n')
Run Code Online (Sandbox Code Playgroud)

来自文档:

os.linesep在文本模式下打开文件时,不要用作行终止符(默认值); 在所有平台上使用单个'\n'代替.

一些有用的阅读:

  • 此示例优于打开/关闭示例.使用`with`是一种更安全的方式来记住关闭文件. (26认同)
  • 我不必调用`the_file.close()`? (11认同)
  • 不,你没有:http://stackoverflow.com/questions/3012488/what-is-the-python-with-statement-designed-for (11认同)
  • @user3226167:这是一个有趣的观点。但是你为什么要打开一个二进制文件来写纯文本呢? (2认同)

sor*_*rin 943

您应该使用print()自Python 2.6+以来可用的功能

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

对于Python 3,您不需要import,因为该 print()函数是默认函数.

另一种方法是使用:

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
Run Code Online (Sandbox Code Playgroud)

引用有关换行符的Python文档:

在输出时,如果换行为None,则'\n'写入的任何字符都将转换为系统默认行分隔符os.linesep.如果换行'',则不进行翻译.如果换行符是任何其他合法值,则'\n'写入的任何字符都将转换为给定的字符串.

  • 不使用`with`语句是一种不好的做法. (47认同)
  • -1"如果你想确定,将os.linesep添加到字符串而不是`\n`"将需要newline =""否则你将在Windows上获得`\ r \n \n \n``.根本没有理由与os.linesep有关. (34认同)
  • @Sorin:您添加写入模式的编辑当然是一种改进.然而,你奇怪地对os.linesep保持顽固态度.看我的回答.顺便说一下,你引用的文档是针对3.x的,但是这部分对于文本模式下的2.x也是有效的:*所写的任何'\n'字符都被转换为系统默认行分隔符,os.linesep**... Windows:编写os.linesep与编写`\ r \n`相同,其中包含`\n`,它被翻译为os.linesep,即`\ r \n`,因此最终结果为`\ r \n\r\N`. (7认同)
  • @John你是对的,我纠正了os.linesep错误.谢谢. (7认同)
  • @BradRuderman这是[POSIX](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_206)标准的一部分,用于构成文本文件中"行"的内容,即每行中的一行文本文件必须以换行符终止,即使是最后一行. (5认同)
  • @sorin为什么使用 file=f 的第一种方法比使用 f.write 的第二种方法更好? (4认同)
  • 为了追加它不是'open('myfile','a')`而是`open('myfile','w')`? (2认同)

j7n*_*n7k 109

Python文档建议是这样的:

with open('file_to_write', 'w') as f:
    f.write('file contents')
Run Code Online (Sandbox Code Playgroud)

所以这就是我通常做的方式:)

来自docs.python.org的声明:

在处理文件对象时,最好使用'with'关键字.这样做的好处是文件在套件完成后正确关闭,即使在途中引发了异常.它也比编写等效的try-finally块短得多.

  • 如何在内部循环? (35认同)

Joh*_*hin 85

关于os.linesep:

这是Windows上未经编辑的未经编辑的Python 2.7.1解释器会话:

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'
>>>
Run Code Online (Sandbox Code Playgroud)

在Windows上:

正如预期的那样,os.linesep确实产生相同的结果一样'\n'.它无法产生相同的结果.'hi there' + os.linesep相当于'hi there\r\n',这是不是等同于'hi there\n'.

就是这么简单:使用\n它会自动转换为os.linesep.自从Python的第一个端口到Windows以来,它就变得如此简单.

在非Windows系统上使用os.linesep毫无意义,它在Windows上产生错误的结果.

不要使用os.linesep!

  • 可以说其他人会阅读它,而不是你,用一些米老鼠软件来解决额外的`\ r`` ... (6认同)
  • @Gusdor:关键是如果你在文本模式下在Windows中明确使用`os.linesep`,结果是`\ r \n \n \n`这是错误的."Windows使用......"毫无意义.C运行时库(以及Python)在文本模式下将输出的`\n`转换为`\ r \n`.其他软件可能表现不同.在文本模式下阅读时,Windows上运行的所有软件都不会将单独的`\n`识别为行分隔符.Python确实如此.微软的记事本文本编辑器没有. (4认同)
  • @Gusdor你是从另一种语言来到python的,使用'\n'会在窗口输出'\n',而不是'\ r \n' - 所以它缺少dumb所期望的'\ r'文字编辑?正如John所说,这不是Python的行为方式 - '\n'会自动被'\ r \n'替换,如果这是os.linesep所说的.因此,在这里明确地说'os.linesep`*是*"错误".它像"冗余部门".是的,你可以做到.不,你不想. (2认同)

Hyp*_*eus 54

我不认为有一种"正确"的方式.

我会用:

with open ('myfile', 'a') as f: f.write ('hi there\n')
Run Code Online (Sandbox Code Playgroud)

在记忆中蒂姆托迪.

  • 呃,是的 这就是使用的想法.如果你想保持文件打开,只需在开始时打开open并在完成后调用close ... (5认同)

Kei*_*ith 21

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

from __future__ import print_function
Run Code Online (Sandbox Code Playgroud)

然后你做

print("hi there", file=f)
Run Code Online (Sandbox Code Playgroud)


Rob*_*kka 17

如果您正在编写大量数据并且速度是您应该关注的问题f.write(...).我做了一个快速的速度比较,它比print(..., file=f)执行大量写入要快得多.

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)
Run Code Online (Sandbox Code Playgroud)

write我的机器上平均完成2.45秒,而print长度约为4倍(9.76秒).话虽如此,在大多数现实世界的情景中,这都不是问题.

如果你选择和print(..., file=f)你一起去,你可能会发现你不时想要压制换行符,或者换成别的东西.这可以通过设置可选end参数来完成,例如;

with open("test", 'w') as f:
    print('Foo1,', file=f, end='')
    print('Foo2,', file=f, end='')
    print('Foo3', file=f)
Run Code Online (Sandbox Code Playgroud)

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

更新:这种性能差异可以解释write为高度缓冲并在实际发生磁盘写入之前返回(参见本答复),而print(可能)使用行缓冲.对此进行简单的测试就是检查长写入的性能,其中线路缓冲的缺点(就速度而言)不太明显.

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")
Run Code Online (Sandbox Code Playgroud)

性能差异现在变得不那么明显了,平均时间为2.20秒write和3.10秒print.如果你需要连接一堆字符串来使这个loooong行性能受到影响,那么print更高效的用例有点罕见.


joh*_*son 9

从3.5开始,您还可以为此使用pathlib

Path.write_text(数据,编码=无,错误=无)

打开以文本模式指向的文件,向其中写入数据,然后关闭文件:

import pathlib

pathlib.Path('textfile.txt').write_text('content')
Run Code Online (Sandbox Code Playgroud)


Zen*_*din 6

如果您想避免自己使用write()orwritelines()和连接字符串与换行符,您可以将所有行传递给print(), 以及换行符分隔符和文件句柄作为关键字参数。此代码片段假设您的字符串没有尾随换行符。

print(line1, line2, sep="\n", file=f)
Run Code Online (Sandbox Code Playgroud)

您不需要在末尾添加特殊的换行符,因为print()它会为您完成。

如果列表中有任意数量的行,则可以使用列表扩展将它们全部传递给print().

lines = ["The Quick Brown Fox", "Lorem Ipsum"]
print(*lines, sep="\n", file=f)
Run Code Online (Sandbox Code Playgroud)

"\n"在 Windows 上用作分隔符是可以的,因为print()它也会自动将其转换为 Windows CRLF 换行符 ( "\r\n")。


小智 6

如果您想在列表中插入每行格式的项目,可以这样开始:

with open('somefile.txt', 'a') as the_file:
    for item in items:
        the_file.write(f"{item}\n")
Run Code Online (Sandbox Code Playgroud)


小智 5

当您说Line时,它表示一些序列化的字符,它们以'\ n'字符结尾。行应该在最后一点,所以我们应该在每行的末尾考虑'\ n'。这是解决方案:

with open('YOURFILE.txt', 'a') as the_file:
    the_file.write('Hello')
Run Code Online (Sandbox Code Playgroud)

在追加模式下,每次写入光标后移至新行,如果要使用“ w”模式,则应在write()函数的末尾添加“ \ n”字符:

the_file.write('Hello'+'\n')
Run Code Online (Sandbox Code Playgroud)

  • “在追加模式下,每次写入后光标都会移动到新行” – 不,不是。 (2认同)