will using list comprehension to read a file automagically call close()

前端 未结 5 1707
独厮守ぢ
独厮守ぢ 2020-11-28 14:32

Does the following syntax close the file:

lines = [line.strip() for line in open(\'/somefile/somewhere\')]

Bonus points if you can demonstr

相关标签:
5条回答
  • 2020-11-28 14:51

    Yes because the "open" does not bound the file handle to any object, it will be closed as soon as the list comprehension is complete as it goes out of scope:

    #!/usr/bin/env python3
    import psutil
    
    print('before anything, open files: ', end='')
    print(psutil.Process().open_files())
    f = open('/etc/resolv.conf')
    print('after opening resolv.conf, open files: ', end='')
    print(psutil.Process().open_files())
    f.close()
    print('after closing resolv.conf, open files: ', end='')
    print(psutil.Process().open_files())
    print('reading /etc/services via a list comprehension')
    services = [ line.strip() for line in open('/etc/services') ]
    print('number of items in services: ', end='')
    print(len(services))
    print('after reading /etc/services through list comp, open files: ', end='')
    print(psutil.Process().open_files())
    
    0 讨论(0)
  • 2020-11-28 14:52

    This is how you should do it

    with open('/somefile/somewhere') as f:
        lines = [line.strip() for line in f]
    

    In CPython the file should be closed right away as there are no references to it left, but Python language does not guarantee this.

    In Jython, the file won't be closed until the garbage collector runs

    0 讨论(0)
  • 2020-11-28 14:58

    This is possible to read and close a file in list comprehension using the more_itertools library1:

    import more_itertools as mit
    
    lines = [line.strip() for line in mit.with_iter(open("/somefile/somewhere"))]
    

    Note more_itertools is a third-party package. Install via pip install more_itertools.

    See also the documentation for more on more_itertools.with_iter.

    0 讨论(0)
  • 2020-11-28 15:00

    It should close the file, yes, though when exactly it does so is implementation dependent. The reason is that there is no reference to the open file after the end of the list comprehension, so it will be garbage collected, and that will close the file.

    In cpython (the regular interpreter version from python.org), it will happen immediately, since its garbage collector works by reference counting. In another interpeter, like Jython or Iron Python, there may be a delay.

    If you want to be sure your file gets closed, its much better to use a with statement:

    with open("file.txt") as file:
        lines = [line.strip() for line in file]
    

    When the with ends, the file will be closed. This is true even if an exception is raised inside of it.

    0 讨论(0)
  • 2020-11-28 15:00

    It will not. A context manager can be used to close it automatically. For example:

    with open('/somefile/somewhere') as handle:
        lines = [line.strip() for line in handle]
    
    0 讨论(0)
提交回复
热议问题