Closing files in Python
In this discussion about the easiest way to run a process and discard its output, I suggested the following code:
with open('/dev/null', 'w') as dev_null:
subprocess.call(['command'], stdout=dev_null, stderr=dev_null)
Another developer suggested this version:
subprocess.call(['command'], stdout=open('/dev/null', 'w'), stderr=STDOUT)
The C++ programmer in me wants to say that when objects are released is an implementation detail, so to avoid leaving a filehandle open for an indeterminate period of time, I should use with
. But a couple of resources suggest that Python always or almost always uses reference counting for code like this, in which c开发者_运维百科ase the filehandle should be reclaimed as soon as subprocess.call
is done and using with
is unnecessary.
(I guess that leaving a filehandle open to /dev/null
in particular is unlikely to matter, so pretend it's an important file.)
Which approach is best?
You are correct, refcouting is not guaranteed. In fact, only CPython (which is the main implementation, yes, but not even remotely the only one) provdies refcounting. In case CPython ever changes that implementation detail (unlikely, yes, but possible), or your code is ever run on an alternate implementation, or you lose refcouting because of any other reason, the file won't be closed. Therefore, and given that the with
statement makes cleanup very easy, I would suggest you always use a context manager when you open files.
When the pipe to the null device closes is irrelevant - it won't lead to data loss in the output or some such. While you maybe want to use the with
variant always to ensure that your output files are always properly flushed and closed, etc., this isn't an example where this matters.
The entire point of the with
statement is to have a controlled cleanup process. You're doing it right, don't let anyone convince you otherwise.
精彩评论