0

Suppose I have a text file called 'text.txt' which contains:

Apple
Orange
Strawberry

Total of 3 lines and I have a class:

class ReadTextFile:
  def __init__(self, filename):
    self.filename = (open(filename, 'r'))

  def number_of_lines(self):
    num = 0

    for line in self.filename:
      line = line.strip("\n")
      num += 1

    return(num)

When I use this class to count the total number of lines, on the first try it gives me a correct answer which is '3', but after that it gives me '0' unless I redefine the variable "text":

>>> text = ReadTextFile('text.txt')
>>> text.number_of_lines()
3
>>> text.number_of_lines()
0
>>> text.number_of_lines()
0
...
>>> text = ReadTextFile('text.txt')
>>> text.number_of_lines()
3
>>> text.number_of_lines()
0
...

What am I doing wrong here?

  • 2
    After you've iterated over the file once, the cursor/pointer/whatever is at the *end* of the file. – jonrsharpe Apr 24 '20 at 17:11
  • `self.filename.seek(0, 0)` – Marat Apr 24 '20 at 17:13
  • It's not necessarily clear what you're trying to achieve here. At the simplest you can seek to the start as above, but there might be better solutions with some context. – jonrsharpe Apr 24 '20 at 17:13
  • Does this answer your question? [Why can't I call read() twice on an open file?](https://stackoverflow.com/questions/3906137/why-cant-i-call-read-twice-on-an-open-file) – Marat Apr 24 '20 at 17:14

2 Answers2

0

Use self.filename.seek(0) to reset the file reader pointer.

Read: Why can't I call read() twice on an open file?

mahieyin-rahmun
  • 1,486
  • 1
  • 12
  • 20
0

The key is to either open the file every time you call your method number_of_lines or atleast do seek to the beginning of the file.

The files object has something like markers (for read and write positions). Once you read a file, a marker is moved to next line to be read. However, once you are at the end of file, they are not going to reset to the beginning of the file. If you try to read again using the same file object, you won't be able to read anything unless you reset the marker using seek().

Try this:

class ReadTextFile:
  def __init__(self, filename):
    self.filename = filename

  def number_of_lines(self):
    num = 0

    with open(self.filename, 'r') as file:
        for line in file:
          num += 1

    return(num)

text = ReadTextFile('txt.txt')
print(text.number_of_lines())
print(text.number_of_lines())
print(text.number_of_lines())
abhiarora
  • 9,743
  • 5
  • 32
  • 57