python试图做一个程序来替换给定的一行,用同一行但是全部CAP

2024-04-19 18:17:30 发布

您现在位置:Python中文网/ 问答频道 /正文

试着做一个大学练习,我应该替换一个文件中给定的一行,替换为同一行,但是用大写字母写。问题是我们只能在同一个文件中写入,而在那一行中,我们不能在文件的其余部分写入。你知道吗

这是我到目前为止的代码,但我不知道如何去我想要的行

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)       

感谢您的帮助!你知道吗


Tags: 文件代码posdefcountwithlineseek
1条回答
网友
1楼 · 发布于 2024-04-19 18:17:30

问题在于您的readlines已经读取了整个文件,因此“文件光标”的位置总是在文件的末尾。理论上,一个简单的解决方法应该是:

  1. pos初始化为0。你知道吗
  2. 读一行。你知道吗
  3. 如果当前行计数器指示这是您想要的,请再次将位置设置为pos,更新该行,然后退出。你知道吗
  4. 更新pos以指向行的末尾(因此它指向下一行的开始)。你知道吗
  5. 循环直到满意。你知道吗

在代码中,应该是这样的:

def upper(n):
    count=0
    with open("text.txt", "r+") as file:
        pos = 0
        for line in file.readlines():
            if count == n:
                line1 = line.upper()
                break

            pos = file.tell()
            count += 1
        file.seek(pos)
        file.write(line1)

upper(5)

但是!遇到了一个障碍。文件操作被大量缓冲,for上的readlines循环一次只读取一行。相反,为了提高效率,它尽可能多地读取,但它只“返回”到程序的下一行。在下一次运行循环时,它只检查是否已经读取了足够的文本文件以返回下一行,如果没有,它将再次填充其内部缓冲区。因此,即使tell()将正确地更新到外部文件位置(即您看到的值),它也不会反映您当时正在处理的内容的“光标”位置。你知道吗

避免这种情况的一种方法是物理模拟readlines的功能:一次读取一个字节,确定是否已读取整行(那么这个字节将是\n),并基于此更新您的位置和状态。你知道吗

然而,更新一个文件的一个更合适的方法是将它全部读入内存,更改它,然后将它写回磁盘。使用"r+"更改现有文件的一部分通常建议使用二进制模式(其中每个字节的位置都是事先知道的);诚然,从理论上讲,您的方法应该也能工作,但正如您所见,文件缓冲会使这一点失效。你知道吗

读取、更改和写入文件非常简单:

def better_upper(n):
    count=0
    with open("text.txt", "r") as file:
        lines = file.readlines()
    lines[n] = lines[n].upper()
    with open("text.txt", "w") as file:
        file.writelines(lines)

better_upper(5)

(这里唯一的警告是它总是覆盖原始文件。也就是说:如果发生意外的错误,它可能会删除text.txt。如果你想要一个皮带和吊带的方法,写一个新的文件,然后检查它是否写得正确。如果有,删除旧文件并重命名新文件。作为练习留给读者。)

相关问题 更多 >