如何在现代Python中向文件写入一行?我听说这是不赞成的:
print >>f, "hi there"
另外,“\n”在所有平台上都可以工作吗,还是我应该在Windows上使用“\r\n”?
如何在现代Python中向文件写入一行?我听说这是不赞成的:
print >>f, "hi there"
另外,“\n”在所有平台上都可以工作吗,还是我应该在Windows上使用“\r\n”?
我认为没有“正确”的方法。
我会用:
with open('myfile', 'a') as f:
f.write('hi there\n')
为了纪念蒂姆·托迪。
您应该使用print()函数,该函数自Python 2.6+以来可用
from __future__ import print_function # Only needed for Python 2
print("hi there", file=f)
对于Python 3,您不需要导入,因为print()函数是默认的。
Python 3中的替代方法是使用:
with open('myfile', 'w') as f:
f.write('hi there\n') # python will convert \n to os.linesep
引用自Python文档中关于换行符的内容:
当写入输出到流时,如果newline为None,则写入的任何'\n'字符都将转换为系统默认的行分隔符os.linesep。如果换行符为''或'\n',则不进行转换。如果newline是任何其他合法值,则写入的任何'\n'字符都将转换为给定的字符串。
参见:读取和写入文件- Python教程
在Python 3中,它是一个函数,但在Python 2中,你可以将它添加到源文件的顶部:
from __future__ import print_function
然后你做了
print("hi there", file=f)
这应该非常简单:
with open('somefile.txt', 'a') as the_file:
the_file.write('Hello\n')
来自文档:
不要使用os。当写入以文本模式打开的文件时(默认),Linesep作为行结束符;在所有平台上使用单个“\n”。
一些有用的阅读:
with语句 open () “a”是“追加”或“使用” 'w'表示截断 操作系统(特别是OS .linesep)
关于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不会产生与'\n'相同的结果。它不可能产生同样的结果。'hi there' + os。linesep等价于'hi there\r\n',它并不等价于'hi there\n'。
很简单:使用\n,它会自动转换为os.linesep。自从第一次将Python移植到Windows以来,就一直如此简单。
使用os没有任何意义。linesep在非Windows系统上,它在Windows上产生错误的结果。
不要使用os.linesep!
python文档推荐这样做:
with open('file_to_write', 'w') as f:
f.write('file contents\n')
所以这是我通常做的方式:)
docs.python.org声明:
在处理文件时使用'with'关键字是一个很好的实践 对象。这样做的好处是文件在关闭后被正确关闭 它的套件结束了,即使在此过程中引发了异常。它是 也比编写等价的try-finally块要短得多。
当你说行,它是指一些以“\n”字符结尾的序列化字符。行应该在最后一点,所以我们应该在每行的末尾考虑'\n'。下面是解决方案:
with open('YOURFILE.txt', 'a') as the_file:
the_file.write("Hello")
在追加模式下,每次写入后光标移动到新行,如果你想使用w模式,你应该在write()函数的末尾添加\n个字符:
the_file.write("Hello\n")
如果你要写很多数据,而且速度很重要,你可能应该使用f.r ay(…)。我做了一个快速的速度比较,它比打印快得多(…, 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)
在我的机器上,平均写用时2.45秒,而打印用时约为4倍(9.76秒)。也就是说,在大多数现实场景中,这不是一个问题。
如果你选择打印(…, file=f)你可能会发现你想要时不时地抑制换行,或者用其他东西替换它。这可以通过设置可选的end参数来完成,例如;
with open("test", 'w') as f:
print('Foo1,', file=f, end='')
print('Foo2,', file=f, end='')
print('Foo3', file=f)
无论您选择哪种方式,我都建议使用with,因为它使代码更容易阅读。
更新:这种性能上的差异是由这样一个事实解释的:写入是高度缓冲的,并且在实际发生写入磁盘之前返回(参见这个答案),而打印(可能)使用行缓冲。对此的一个简单测试是检查长写入的性能,这样行缓冲的缺点(就速度而言)就不那么明显了。
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")
现在,性能差异变得不那么明显了,写入的平均时间为2.20秒,打印的平均时间为3.10秒。如果需要连接一堆字符串来获得这种长行性能将受到影响,因此打印效率更高的用例有点少见。
你也可以这样使用io模块:
import io
my_string = "hi there"
with io.open("output_file.txt", mode='w', encoding='utf-8') as f:
f.write(my_string)
从3.5开始,你也可以使用pathlib来实现这个目的:
路径。write_text(data, encoding=None, errors=None) 以文本模式打开指向的文件,向其写入数据,然后关闭文件:
import pathlib
pathlib.Path('textfile.txt').write_text('content')
你也可以试试文件编辑器
PIP安装文件写入器
from filewriter import Writer
Writer(filename='my_file', ext='txt') << ["row 1 hi there", "row 2"]
写入my_file.txt
接受一个可迭代对象或具有__str__支持的对象。
当我需要大量编写新行时,我定义了一个使用print函数的lambda:
out = open(file_name, 'w')
fwl = lambda *x, **y: print(*x, **y, file=out) # FileWriteLine
fwl('Hi')
这种方法的好处是它可以利用打印函数的所有可用特性。
更新:正如Georgy在评论区提到的,可以通过partial函数进一步改进这个想法:
from functools import partial
fwl = partial(print, file=out)
恕我直言,这是一种更实用、更简单的方法。
在烧瓶文件中写入文本可以使用:
filehandle = open("text.txt", "w")
filebuffer = ["hi","welcome","yes yes welcome"]
filehandle.writelines(filebuffer)
filehandle.close()
如果您希望避免使用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”)。
既然其他人已经回答了如何做到这一点,我将逐行回答它是如何发生的。
with FileOpenerCM('file.txt') as fp: # is equal to "with open('file.txt') as fp:"
fp.write('dummy text')
这就是所谓的context manager, with block中的任何东西都是context manager。让我们看看这是如何发生的。
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,但我看到类更干净。
如果你想在列表中以每行格式插入项目,一种开始的方式可以是:
with open('somefile.txt', 'a') as the_file:
for item in items:
the_file.write(f"{item}\n")