[Python-Dev] Destructors and Closing of File Objects

Nikolaus Rath Nikolaus at rath.org
Fri Apr 12 07:04:45 CEST 2013

[ Note: I already asked this on
http://stackoverflow.com/questions/15917502 but didn't get any
satisfactory answers]


The description of tempfile.NamedTemporaryFile() says:

|  If delete is true (the default), the file is deleted as soon as it is
|  closed.

In some circumstances, this means that the file is not deleted after the
program ends. For example, when running the following test under
py.test, the temporary file remains:

| from __future__ import division, print_function, absolute_import
| import tempfile
| import unittest2 as unittest
| class cache_tests(unittest.TestCase):
|     def setUp(self):
|         self.dbfile = tempfile.NamedTemporaryFile()
|     def test_get(self):
|         self.assertEqual('foo', 'foo')

In some way this makes sense, because this program never explicitly
closes the file object. The only other way for the object to get closed
would presumably be in the __del__ destructor, but here the language
references states that "It is not guaranteed that __del__() methods are
called for objects that still exist when the interpreter exits." So
everything is consistent with the documentation so far.

However, I'm confused about the implications of this. If it is not
guaranteed that file objects are closed on interpreter exit, can it
possibly happen that some data that was successfully written to a
(buffered) file object is lost even though the program exits gracefully,
because it was still in the file objects buffer and the file object
never got closed?

Somehow that seems very unlikely and un-pythonic to me, and the open()
documentation doesn't contain any such warnings either. So I
(tentatively) conclude that file objects are, after all, guaranteed to
be closed.

But how does this magic happen, and why can't NamedTemporaryFile() use
the same magic to ensure that the file is deleted? 



 »Time flies like an arrow, fruit flies like a Banana.«

  PGP fingerprint: 5B93 61F8 4EA2 E279 ABF6  02CF A9AD B7F8 AE4E 425C

More information about the Python-Dev mailing list