为什么文件中的内容被替换?

时间:2019-06-26 15:07:46

标签: python file file-handling

我是Python的初学者。我打开了一个文件,并尝试使用 TextReader 类用它替换旧数据。

我已经尝试过多次在PyCharm上调试代码,但我不知道发生了什么。

这是TextReader类。

class TextReader:
    def __init__(self, spec):
       self.file = open(spec, 'r+')
       self.text = self.file.read()
       self.lines = 0
       for _ in self.file:
           self.lines += 1

    def replace(self, old, new):
        replace = ''
        for line in self.file:
            replace += line.replace(old, new) + '\n'
        self.file.write(replace)

t = TextReader('temp.txt')
t.replace('good', 'bad')
print(t.text)
print(t.lines)

在运行程序之前,temp.txt包含:-

Python is a good programming language.

这是以下代码的输出:-

0

我在运行程序后打开temp.txt文件,发现它为空。 请帮忙!

3 个答案:

答案 0 :(得分:1)

file对象具有一个内部文件“偏移量”,只要您对该文件进行读/写/查找,该文件就会更改。因此,您多次隐式地读到结尾,而从未seek回到任何地方,例如:

  1. 您的file.read()将一直读取直到文件结尾
  2. 您会for _ in self.filefor line in self.file遍历每一行

所有这些将在最后保留偏移量。如果您没有seek重新回到开头,那么所有这些操作都是从“当前偏移量”开始的,您将一无所获

我建议按照@tripleee的建议进行操作,并阅读一次,然后将其拆分为几行,然后进行处理,而不是反复尝试从文件的不同部分重新读取相同的数据

答案 1 :(得分:1)

文件是Python中的迭代器,因此您只能读取一次文件句柄。您需要在这里尝试读取相同的句柄三遍,所以最后两遍什么也不做:

class TextReader:
    def __init__(self, spec):
       self.file = open(spec, 'r+') 
       self.text = self.file.read() # < reads the iterator -- it is now spent
       self.lines = 0
       for _ in self.file:          # < try to read again does nothing
           self.lines += 1          # < this never runs

    def replace(self, old, new):
        replace = ''
        for line in self.file:      # < try to read again; loop again doesn't run
            replace += line.replace(old, new) + '\n'
        self.file.write(replace)

如果要计数行数,以后再一一读取,只需将文件读入列表即可。然后count将是列表的长度。像这样:

class TextReader:
    def __init__(self, spec):
        self.file = open(spec, 'r+')
        # alternative to below:
        # self.lines = list(self.file)
        self.lines = []
        for line in self.file:
            self.lines.append(line)

    def replace(self, old, new):
        replace = ''
        for line in self.lines:
            replace += line.replace(old, new) + '\n'
        self.file.write(replace)
        self.file.close()       # remember to close the file!

t = TextReader('test.txt')
t.replace('good', 'bad')
print(t.lines)
print(len(t.lines))

这将导致文件包含两行-您的原始行和由good替换为bad的附加行。这是因为您以r+开头,这意味着附加。

答案 2 :(得分:1)

其他答案解释了为什么您的代码无法正常工作。因此,正确的做法是您需要在完成后关闭文件,否则可能导致内存泄漏。另外,我建议您使用with,因为它会自动为您打开和关闭文件。这就是我要做的。

class TextReader:
   def __init__(self, spec):
      self.file = spec
      self.text = ''
      self.lines = 0
      with open(spec, 'r') as f:
         for line in f:
            self.text += line
            self.lines += 1

   def replace(self, old, new):
      with open(self.file, "w") as f:
         r = ''
         for line in self.text.split("\n"):
            r += line.replace(old, new) + '\n'
         f.write(r)

t = TextReader('temp.txt')
t.replace('good', 'bad')
print(t.text)
print(t.lines)

它会自动为您关闭文件,然后重新打开以覆盖当前文本以替换所需的单词,因为“ r +”将附加到文件末尾。