2

My question is, what happens to the file object created inside a generator expression after the generator's iterator is exhausted? Has close been called on it? or this benefit only comes while reading file using with statement?

Example

my_file = (nth_row for nth_row in open(file_path, "rt"))

while True:
    try:
        print(next(my_file))

    except StopIteration:
        print("End of the file")
        break

Alireza Amani
  • 179
  • 1
  • 4
  • 12
  • 1
    The file object is not closed unless it is closed by explicitly calling `.close()` on it or it is implicitly called by exiting a `with` statement block. – larsks Oct 13 '22 at 00:05

2 Answers2

1

The close() method is not called. Generator expressions don't behave like with statements; they don't care whether you use a context manager. The code may result in a memory leak. Generally, the garbage collector will close the file, but that's not guaranteed. You could wrap the whole thing in a with block:

with open(file_path, "rt") as file:
    my_file = (nth_row for nth_row in file)
    
    while True:
        try:
            print(next(my_file))
    
        except StopIteration:
            print("End of the file")
            break

If you want to read the file in chunks, see Lazy Method for Reading Big File in Python? You can replace the .read(chunk_size) with readline() if you want.

pigrammer
  • 2,603
  • 1
  • 11
  • 24
1

You can check it explicitly like this:

file = open(file_path, "rt")

my_file = (nth_row for nth_row in file)

while True:
        try:
                print(next(my_file))

        except StopIteration:
                print("End of the file")
                print(f"File closed in the current process: {file.closed}")
                break

the file object is still open (in the current process).

Jonathan Ciapetti
  • 1,261
  • 3
  • 11
  • 16