473,386 Members | 1,790 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

Questions about file object and close()

Hi,

Does anyone see a problem with doing:
data = file("tata").read()

Each time this is done, I see a new file
descriptor allocated (Linux) but not
released.

1) Will there ever be a point where I
will have a problem with file
descriptors because the garbage
collector has _not_ yet collected the
file objects?

2) When I subclassed the file object as
follows:
-----
class MyFile(file):
def close(self):
print "MyFile.close()"
file.close(self)
-----
and did a simple 'MyFile("tata")' I did not see
a call to MyFile.close(). Am I wrong to have
expected MyFile.close() to have been called?

3) There is no file.__del__() as far as I
can tell at the Python level. Are files
opened by the calls above properly
closed when the objects are destroyed
and collected?

Thanks,
John

Jul 18 '05 #1
5 2105
John Marshall wrote:
Hi,

Does anyone see a problem with doing:
data = file("tata").read()

Each time this is done, I see a new file
descriptor allocated (Linux) but not
released.

1) Will there ever be a point where I
will have a problem with file
descriptors because the garbage
collector has _not_ yet collected the
file objects?
Should be easy to check. Write a loop which
does that many times. There are a finite
number of file descriptors available, so if
it's going to fail, it will fail fairly
quickly.
3) There is no file.__del__() as far as I
can tell at the Python level. Are files
opened by the calls above properly
closed when the objects are destroyed
and collected?


Yes, but you can only count on this happening
in the CPython implementation. Nevertheless,
it's still widely considered more than just good style
to explicitly close your files within a finally
clause, even in CPython where technically you don't
have to in most cases:

f = file("tata")
try:
data = f.read()
finally:
f.close()

The above is quite robust and should be your model
for all file access, at least until you're much more
experienced with Python.

One should use the open().read() idiom only in small
utility scripts and other such short-running applications.

-Peter
Jul 18 '05 #2
On Thu, 2004-12-09 at 08:41 -0500, Peter Hansen wrote:
John Marshall wrote:
Hi,

Does anyone see a problem with doing:
data = file("tata").read()

Each time this is done, I see a new file
descriptor allocated (Linux) but not
released.

1) Will there ever be a point where I
will have a problem with file
descriptors because the garbage
collector has _not_ yet collected the
file objects?
Should be easy to check. Write a loop which
does that many times. There are a finite
number of file descriptors available, so if
it's going to fail, it will fail fairly
quickly.


I did do this and it did not fail. My concern
was since the close() is not done explicitly
by me, and does not seem to be called in
a file.__del__() or otherwise, I was not
sure. I want to be sure! Given your comment
below about the CPython implementation, there
is no guarantee which seems unreasonable for
such an operation.

It seems to me that a file.__del__() _should_
call a file.close() to make sure that the file
is closed as a clean up procedure before
releasing the object. I cannot see why this
would not be the prescribed behavior and thus
my question. Isn't that what __del__
(destructors) are supposed to handle--cleaning
up?
3) There is no file.__del__() as far as I
can tell at the Python level. Are files
opened by the calls above properly
closed when the objects are destroyed
and collected?


Yes, but you can only count on this happening
in the CPython implementation. Nevertheless,
it's still widely considered more than just good style
to explicitly close your files within a finally
clause, even in CPython where technically you don't
have to in most cases:

f = file("tata")
try:
data = f.read()
finally:
f.close()

The above is quite robust and should be your model
for all file access, at least until you're much more
experienced with Python.


How would more experience change this? Assuming I
am catching any exceptions I am interested in, why
wouldn't the following be just as good?
try:
data = file("tata").read()
except:
...

One should use the open().read() idiom only in small
utility scripts and other such short-running applications.


I don't see why this is so only for small scripts. As
I question above, why doesn't the file object clean up
after itself as a guaranteed course of action?

Of course, I could implement my own file object to
guarantee the clean up and be on my way. But I am
still surprised at what I am seeing.

Thanks,
John

Jul 18 '05 #3
John Marshall wrote:
It seems to me that a file.__del__() _should_
call a file.close() to make sure that the file
is closed as a clean up procedure before
releasing the object.
I believe it does, but I tried your experiment
with subclassing file and didn't ever see a
call to close, so I can only assume that the
built-in __del__() is actually just calling the
builtin close() and bypassing my overridden close(),
although there could also be some other magic about
how files behave that explains this.
I don't see why this is so only for small scripts. As
I question above, why doesn't the file object clean up
after itself as a guaranteed course of action?


The issue is that although __del__ is calling
close, there is no guarantee in Python about when
__del__ is run, nor in fact that it will ever be
run. (If nothing else, a call to os._exit() will
always bypass normal shutdown.) In Jython, for
example, there is no reference counting the way CPython
does it, so __del__ methods are called only when the
object is garbage collected. When does that happen?
There's no guarantee: if you haven't explicitly closed
the file, it might not get closed until the interpreter
is shutting down (if then).

In CPython, you at least (currently) have sort of a
guarantee that the file will be closed when the object
is destroyed, which because of reference counting will
happen as soon as you "del file" or rebind the name
to another object, or whatever.

So in CPython, it is working properly (and you shouldn't
run out of file descriptors unless you are into
complicated code where the file objects are being kept
in cyclical data structures that cannot be reclaimed
through simple reference counting) but I cannot explain
why we don't see a subclass's close() method get called
when __del__ does, as it must, get called.

-Peter
Jul 18 '05 #4
John Marshall wrote:
On Thu, 2004-12-09 at 08:41 -0500, Peter Hansen wrote:
John Marshall wrote:
Does anyone see a problem with doing:
data = file("tata").read()

... a perfectly good explanation....


It seems to me that a file.__del__() _should_
.... how he wishes it were designed ....
Isn't that what __del__ (destructors) are supposed to handle
--cleaning up?


Just in case you are actually asking, and not simply complaining:

The existence of a __del__ method affects when a garbage collect
may remove an object (and may in some cases delay it). In Jython
(and on top of any system doing its own garbage collection),
there may be no control over when an object is deallocated.
A close on an output file may finalize I/O that has been considered
a mistake, and it might cause an I/O error that will prevent the rest
of the program from executing.
One should use the open().read() idiom only in small
utility scripts and other such short-running applications.


I don't see why this is so only for small scripts. As
I question above, why doesn't the file object clean up
after itself as a guaranteed course of action?


If you really want, define a function like:

def contents(filename):
source = open(filename)
try:
return source.read()
finally:
source.close()

and then you can make your small uses clear.
-Scott David Daniels
Sc***********@Acm.Org
Jul 18 '05 #5
On Thu, 2004-12-09 at 10:33 -0500, Peter Hansen wrote:
John Marshall wrote:
It seems to me that a file.__del__() _should_
call a file.close() to make sure that the file
is closed as a clean up procedure before
releasing the object.


I believe it does, but I tried your experiment
with subclassing file and didn't ever see a
call to close, so I can only assume that the
built-in __del__() is actually just calling the
builtin close() and bypassing my overridden close(),
although there could also be some other magic about
how files behave that explains this.


I took a look at the filemodule.c code and in the
file_dealloc() which is registered as the destructor,
a close() is done on the file as your surmised.
In fact, the file_dealloc() does not even call
the file_close() but simply does an OS close().
I don't see why this is so only for small scripts. As
I question above, why doesn't the file object clean up
after itself as a guaranteed course of action?


The issue is that although __del__ is calling
close, there is no guarantee in Python about when
__del__ is run, nor in fact that it will ever be
run.

In CPython, you at least (currently) have sort of a
guarantee that the file will be closed when the object
is destroyed, which because of reference counting will
happen as soon as you "del file" or rebind the name
to another object, or whatever.

So in CPython, it is working properly (and you shouldn't
run out of file descriptors unless you are into
complicated code where the file objects are being kept
in cyclical data structures that cannot be reclaimed
through simple reference counting) but I cannot explain
why we don't see a subclass's close() method get called
when __del__ does, as it must, get called.


Thanks for the explanation. After reading some of
the comp.lang.python stuff it seems that an improvement
to the Python FAQ would be worthwhile (unless I've
missed something else in it). The FAQ (1.6.11) says,
The del statement does not necessarily call
__del__ -- it simply decrements the object's
reference count, and if this reaches zero __del__
is called.

This really does communicate that Python (not
unambiguously CPython only, as of 2004-12-09) will
call __del__ when refcount == 0.

It seems that if one cannot expect __del__ to be
called when nothing references it (using any GC
approach) then its only use is to free
memory/objects not to release other resources such
as file descriptors, socket descriptors, etc.
Thus the recommendation to explicitly do a
file.close() after reading.

Thanks,
John

Jul 18 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: David Stockwell | last post by:
Hi, Another of my crazy questions. I'm just in the process of learning so bear with me if you can. I actually ran it.... with two test cases TEST CASE 1: Say I have the following defined:...
37
by: middletree | last post by:
Yesterday, I posted a problem which, by the way, I haven't been able to solve yet. But in Aaron's reply, he questioned why I did several things the way I did. My short answer is that I have a lot...
11
by: pradeep_TP | last post by:
Hi all, I have a few questions that I have been wanting to ask for long. These are all related to ADO.net and specifically to conenction to database. 1) If I have opened a connection to a...
9
by: Patrick.O.Ige | last post by:
I have a code below and its a PIE & BAR CHART. The values now are all static but I want to be able to pull the values from a database. Can you guys give me some ideas to do this? Thanks ...
1
by: The Eeediot | last post by:
Hello, ASP.NET gurus! I have read many pages on setting up a login screen to access a number of web pages using Forms Authentication and I am still trying to wrap my brain around the whole thing. ...
6
by: Teresa | last post by:
1) If I do want to keep an object alive throughout the live of an application, how can I ensure that the GC doesn't clean it up? 2a) How do I determine if an object is a managed or an unmanged...
5
by: iTISTIC | last post by:
Developing a new app and am trying to make this my first truly OOP/3-Tier app. I understand the principles of the presentation, business, and data layers. I do, however, have some questions on...
14
by: shamirza | last post by:
Question Do ActiveX DLLs made in VB still need the VB runtimes on the machine? ________________________________________ Answer In a word, Yes. Visual Basic does not support what is known...
2
by: John | last post by:
I am trying to familiarize myself with filestreams, but I have run into the following issues. I am hoping that someone can shed some light on these issues for me please. I am using the...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.