我习惯做print >>f, "hi there"
但是,print >>
似乎已被弃用。上面这一行的推荐方法是什么?
更新的:
关于"\n"
的所有答案......是普遍的还是特定于Unix的? IE,我应该在Windows上进行"\r\n"
吗?
答案 0 :(得分:936)
您应该使用自Python 2.6 +
以来可用的print()
函数
from __future__ import print_function # Only needed for Python 2
print("hi there", file=f)
对于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
引自Python documentation有关换行符的信息:
在输出时,如果换行为“无”,则写入的任何
'\n'
个字符都将转换为系统默认行分隔符os.linesep
。如果换行符为''
,则不会进行翻译。如果换行符是任何其他合法值,则写入的任何'\n'
个字符都将转换为给定的字符串。
答案 1 :(得分:897)
这应该简单如下:
with open('somefile.txt', 'a') as the_file:
the_file.write('Hello\n')
来自文档:
在编写以文本模式打开的文件时,不要使用
os.linesep
作为行终止符(默认值);在所有平台上使用单个'\ n'。
一些有用的阅读:
with
statement open()
os
(特别是os.linesep
)答案 2 :(得分:105)
python docs推荐这种方式:
with open('file_to_write', 'w') as f:
f.write('file contents')
所以这就是我通常这样做的方式:)
来自docs.python.org的声明:
在处理文件时,最好使用'和'关键字 对象。这样做的好处是文件在之后正确关闭 即使在途中出现异常,它的套件也会完成。它是 也比编写等效的try-finally块短得多。
答案 3 :(得分: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'
>>>
在Windows上:
正如预期的那样,os.linesep确实 NOT 产生与'\n'
相同的结果。它无法产生相同的结果。 'hi there' + os.linesep
相当于'hi there\r\n'
, NOT 等同于'hi there\n'
。
就是这么简单:使用\n
将自动转换为os.linesep。从Python的第一个端口到Windows,它就变得非常简单。
在非Windows系统上使用os.linesep是没有意义的,它会在Windows上产生错误的结果。
请勿使用os.linesep!
答案 4 :(得分:52)
答案 5 :(得分:20)
在Python 3中它是一个函数,但在Python 2中,您可以将它添加到源文件的顶部:
from __future__ import print_function
然后你做
print("hi there", file=f)
答案 6 :(得分:16)
如果您正在编写大量数据并且速度是一个问题,那么您应该使用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)
平均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)
无论您选择哪种方式,我都建议使用with
,因为它使代码更容易阅读。
更新:这种性能差异可以解释为write
高度缓冲并在实际发生磁盘写入之前返回(参见this answer),而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")
性能差异现在变得不那么明显,write
的平均时间为2.20秒,print
的平均时间为3.10秒。如果你需要连接一堆字符串来使这个loooong行性能受到影响,那么print
效率更高的用例有点罕见。
答案 7 :(得分:8)
从3.5开始,您也可以为此使用pathlib:
Path.write_text(数据,编码=无,错误=无)
打开以文本模式指向的文件,向其中写入数据,然后关闭文件:
import pathlib
pathlib.Path('textfile.txt').write_text('content')
答案 8 :(得分:4)
当你说Line时它意味着一些序列化的字符,这些字符以'\ n'字符结尾。线应该在某个时刻持续,所以我们应该在每一行的末尾考虑'\ n'。这是解决方案:
with open('YOURFILE.txt', 'a') as the_file:
the_file.write('Hello')
在每次写入后的追加模式中光标移动到新行,如果你想使用'w'模式,你应该在write()函数的末尾添加'\ n'个字符:
the_file.write('Hello'+'\n')
答案 9 :(得分:3)
一个人也可以使用io
模块,如下所示:
import io
my_string = "hi there"
with io.open("output_file.txt", mode='w', encoding='utf-8') as f:
f.write(my_string)
答案 10 :(得分:1)
如果您想在列表中插入每行格式的项目,一种开始方式可能是:
with open('somefile.txt', 'a') as the_file:
for item in python_list_of_strings:
the_file.write(f"{item}\n")
答案 11 :(得分:0)
您也可以尝试filewriter
pip install filewriter
from filewriter import Writer
Writer(filename='my_file', ext='txt') << ["row 1 hi there", "row 2"]
写入my_file.txt
采用支持__str__
的可迭代对象或对象。
答案 12 :(得分:0)
当我需要大量编写新行时,我定义一个使用print
函数的lambda:
out = open(file_name, 'w')
fwl = lambda *x, **y: print(*x, **y, file=out) # FileWriteLine
fwl('Hi')
这种方法的优势在于它可以利用print
函数提供的所有功能。
更新:正如Georgy在评论部分中提到的那样,可以通过partial
函数来进一步改善这一想法:
from functools import partial
fwl = partial(print, file=out)
恕我直言,这是一种功能更强,含糊不清的方法。
答案 13 :(得分:0)
可以使用烧瓶中的文件写文本:
filehandle = open("text.txt", "w")
filebuffer = ["hi","welcome","yes yes welcome"]
filehandle.writelines(filebuffer)
filehandle.close()
答案 14 :(得分:0)
如果要避免使用write()
或writelines()
并自己将字符串与换行符连接,则可以将所有行传递到print()
以及换行符分隔符和文件中作为关键字参数处理。此代码段假定您的字符串没有尾随换行符。
print(line1, line2, sep="\n", file=f)
您不需要在末尾添加特殊的换行符,因为print()
可以帮您实现这一点。
如果列表中有任意行,则可以使用列表扩展将它们全部传递给print()
。
lines = ["The Quick Brown Fox", "Lorem Ipsum"]
print(*lines, sep="\n", file=f)
在Windows上可以使用"\n"
作为分隔符,因为print()
还将自动将其转换为Windows CRLF换行符("\r\n"
)。
答案 15 :(得分:0)
由于其他人已经回答了如何做,所以我将逐行回答它的发生情况。
with FileOpenerCM('file.txt') as fp: # is equal to "with open('file.txt') as fp:"
fp.write('dummy text')
这是所谓的context manager
,with
块附带的任何内容都是上下文管理器。让我们看看它是如何发生的。
class FileOpenerCM:
def __init__(self, file, mode='w'):
self.file = open(file, mode)
def __enter__(self):
return self.file
def __exit__(self, exc_type, exc_value, exc_traceback):
self.file.close()
第一个方法__init__
是(众所周知)对象的初始化方法。每当创建对象obj.__init__
时,都必须调用它。这就是您放置所有init类代码的地方。
第二种方法__enter__
有点有趣。你们中的有些人可能没有看到它,因为它是上下文管理器的特定方法。它返回的是在as
关键字之后要分配给变量的值。在我们的情况下为fp
。
最后一个方法是捕获错误或代码退出with块后运行的方法。 exc_type
,exc_value
,exc_traceback
变量是保存在block内部发生的错误的值的变量。例如,
exc_type: TypeError
exc_value: unsupported operand type(s) for +: 'int' and 'str
exc_traceback: <traceback object at 0x6af8ee10bc4d>
从前两个变量中,您可以获得有关错误的足够信息。老实说,我不知道第三个变量的用法,但是对我来说,前两个就足够了。如果您确实想对上下文管理器进行更多研究,则可以这样做,并请注意,编写类并不是编写上下文管理器的唯一方法。使用contextlib,您还可以通过函数(实际上是生成器)编写上下文管理器。完全由您决定。你一定可以尝试 生成器函数与contextlib一起使用,但我认为类更整洁。