试着做一个大学练习,我应该用一个文件替换文件中的给定行,但是用全部大写写.问题是我们只能写在同一个文件中,在那个确切的行中,我们不能写入文件的其余部分.
这是我到目前为止的代码,但我无法弄清楚如何去我想要的行
def upper(n):
count=0
with open("upper.txt", "r+") as file:
lines = file.readlines()
file.seek(0)
for line in file.readlines():
if count == n:
pos = file.tell()
line1 = str(line.upper())
count += 1
file.seek(pos)
file.write(line1)
Run Code Online (Sandbox Code Playgroud)
帮助赞赏!
问题在于您readlines 已经读取了整个文件,因此“文件光标”的位置始终位于文件末尾。理论上,一个简单的修复应该是:
pos为0。pos,更新该行,然后退出。pos为指向该行的末尾(因此它指向下一行的开头)。在代码中,那就是这样的:
\n\ndef upper(n):\n count=0\n with open("text.txt", "r+") as file:\n pos = 0\n for line in file.readlines():\n if count == n:\n line1 = line.upper()\n break\n\n pos = file.tell()\n count += 1\n file.seek(pos)\n file.write(line1)\n\nupper(5)\nRun Code Online (Sandbox Code Playgroud)\n\n然而!有一个障碍。文件操作被大量缓冲,并且for循环readlines不会一次读取一行。相反,为了提高效率,它会读取尽可能多的内容,但它仅将下一行“返回”到您的程序。在下次运行循环时,它只是检查是否已经读取了足够的文本文件以返回下一行,如果没有,它会再次填充其内部缓冲区。因此,即使您看到的值 \xe2\x80\x93tell()正确更新到外部文件位置 \xe2\x80\x93 ,它也不会反映您当时正在处理的“光标”位置。
规避此readlines问题的一种方法是在物理上模仿:一次读取一个字节,确定您是否已读取整行(然后该字节将为\\n),并据此更新您的位置和状态。
然而,更新文件的更正确方法是将其完整读入内存,更改它,然后写回磁盘。通常建议使用二进制模式更改现有文件的一部分"r+"(其中每个字节的位置事先已知);诚然,理论上你的方法应该也有效,但正如你所看到的,文件缓冲击败了这一点。
读取、更改和写入文件就这么简单:
\n\ndef better_upper(n):\n count=0\n with open("text.txt", "r") as file:\n lines = file.readlines()\n lines[n] = lines[n].upper()\n with open("text.txt", "w") as file:\n file.writelines(lines)\n\nbetter_upper(5)\nRun Code Online (Sandbox Code Playgroud)\n\n(唯一需要注意的是,它总是会覆盖原始文件。也就是说:如果出现意外问题,它可能会删除text.txt。如果您想要一种安全带方法,请写入一个新文件,然后检查它是否得到了写得正确。如果是这样,请删除旧文件并重命名新文件。留给读者作为练习。)
| 归档时间: |
|
| 查看次数: |
66 次 |
| 最近记录: |