4

It is typically said that you should use a with statement when working with files in python, so that regardless of whether the operations on the file succeed the file will be closed. For example:

with open('somefile') as f:
    # do stuff to file

instead of something like:

try:
    f = open('somefile')
    # do stuff to file
except Exception as e:
    print 'error: %s' % e
finally:
    f.close()

However, I've also heard that Python's GC will take care of it anyway, so it isn't necessary.

Is this true? If so, why is it a pattern commonly suggested?

stantonk
  • 1,922
  • 1
  • 18
  • 24
  • gc is not what you can't expect from and taken into account. it's a good habbit anyway. – Jason Hu Mar 20 '15 at 17:37
  • That won't work if the exception happens while opening the file, since it won't be able to close it. so you might want to put the `f = open('somefile')` before the **try** statement. otherwise, don't see why it would not work – Julien Spronck Mar 20 '15 at 17:38
  • what? ... I didnt understand a lot of that comment @HuStmpHrrr.... in CPython, especially for reading, it is really not necessary ... (that said it is a good habbit (I agree with that) to wrap it in the `with` statement) – Joran Beasley Mar 20 '15 at 17:38
  • 1
    @JoranBeasley http://overcompensating.com/oc/index.php?comic=272 – jonrsharpe Mar 20 '15 at 17:40
  • there fixed :P thats why I wasnt an english major :P @jonrsharpe – Joran Beasley Mar 20 '15 at 17:41
  • There are really two things involved. The first is reference counting (delete the object at the point where its references reach zero) which does 99% of the job, and the second is garbage collection which works with objects that have weird references (like circular references) that are not detected by the first method. – tdelaney Mar 20 '15 at 17:42
  • @JoranBeasley FWIW I did a degree in Physics! – jonrsharpe Mar 20 '15 at 17:42
  • @JoranBeasley `unnecessary` is really not a good word to allow a programmer to bring mess, even though some environment can collect some mess. – Jason Hu Mar 20 '15 at 17:44
  • The CPython GC will take care of it in *most* cases. However, that is not the only version of Python. PyPy's GC behaves quite differently, and may take way longer to clean it up. Other implementations may not clean it up at all. Using with makes it clearer to the interpreter *and to other developers* how long you need the file to be open. – Jeremy Mar 20 '15 at 17:44
  • 1
    I find the `with` clause requirement very annoying. Things like `reader = csv.reader(open('somefile.csv'))` also fall prey to its demands. – tdelaney Mar 20 '15 at 17:44
  • Its perfectly safe in CPython, especially when you are just reading ... not good practice since its an implementation detail and in general it is recommended to avoid doing this ... (I still do it regularly though) – Joran Beasley Mar 20 '15 at 17:44
  • there are some situations where the GC may not get to run (interpreter segfaults, or `kill -9`ing the interpreter's process, for example) – roippi Mar 20 '15 at 18:06
  • @roippi - its reference counting, not garbage collection, at play here. – tdelaney Mar 20 '15 at 18:13
  • @tdelaney yes, and gc runs when refcount drops to 0, which only happens at the end of your file if you don't use a `with` statement, so... – roippi Mar 20 '15 at 18:16
  • i have never ever *ever* ever seen opening a fh in read mode breaking when using CPython regardless of with statement ... that said I do understand full well that its bad practice to rely on an implementation detail – Joran Beasley Mar 20 '15 at 18:26

0 Answers0