On Sun, 05 Apr 2009 15:51:31 +1200, Lawrence D'Oliveiro wrote: > All Python objects are reference-counted. Once the file object becomes > inaccessible, it is automatically closed. Simple.
If only it were so simple. Firstly, what you describe is an implementation detail of CPython, not Python the language. Jython does not close files as soon as they become inaccessible, and IronPython and CLPython may not. Secondly, even in CPython things may not be so simple. Not all file-like objects are built-in file objects. >>> class MyFile(file): ... pass ... >>> f = MyFile("test", "r") >>> n = f.fileno() >>> os.read(n, 1) 'h' >>> f.close() >>> os.read(n, 1) Traceback (most recent call last): File "<stdin>", line 1, in <module> OSError: [Errno 9] Bad file descriptor My file-like object works just like the built-in file object, but now I can do this: >>> f = MyFile("test", "r") >>> f.attr = f # make a reference cycle >>> n = f.fileno() >>> del f >>> os.read(n, 5) 'hello' And lo and behold, the file is *not* automatically closed when f becomes inaccessible. I don't believe the garbage collector will free that file descriptor, possibly not even when Python exists. But watch this: >>> os.close(n) # just to be sure >>> >>> from __future__ import with_statement >>> with MyFile("test", "r") as f: ... n = f.fileno() ... f.attr = f # make a reference cycle ... >>> os.read(n, 5) Traceback (most recent call last): File "<stdin>", line 1, in <module> OSError: [Errno 9] Bad file descriptor The with statement guarantees[1] closing, even if there are other references to the file object elsewhere. [1] Guarantee void if the file system can't actually close the file for some reason. -- Steven -- http://mail.python.org/mailman/listinfo/python-list