Isopycnal Oscillation
Isopycnal Oscillation

Reputation: 3384

Python: If I specify stdout with open file function does it close automatically?

Example:

subprocess.call(cmd, stdout=open('status_grid','a'), cwd = folder)

is the file status_grid closed automatically?

Upvotes: 0

Views: 143

Answers (4)

unutbu
unutbu

Reputation: 880657

If not done explicitly, the file will be closed when it is garbage collected. When the file is garbage collected is not specified by the Python language per se.

In CPython, the file is garbage collected when there are no more references to the file object.

With other implementations of Python, such as Jython, garbage collection may happen completely differently:

Jython has "true" garbage collection whereas CPython uses reference counting. This means that in Jython users don't need to worry about handling circular references as these are guaranteed to be collected properly. On the other hand, users of Jython have no guarantees of when an object will be finalized -- this can cause problems for people who use open("foo", 'r').read() excessively. Both behaviors are acceptable -- and highly unlikely to change.


As EMS and Charles Salvia point out, to be sure when the file is closed, it is best to not leave it up to the garbage collector. The best way to do that is to use a with statement, which guarantees the file will be closed when Python leaves the with-suite:

with open('status_grid','a') as f:
    subprocess.call(cmd, stdout=f, cwd = folder)

Upvotes: 2

korylprince
korylprince

Reputation: 3009

No, it doesn't:

import subprocess
f = open('b','a')
subprocess.call('ls', stdout=f)
print f.closed

Output:

False

Now a better answer might come from unutbu. You don't give your open file a reference, so once your subprocess completes, it's up to the garbage collector how much longer the file is open.

Upvotes: 3

Charles Salvia
Charles Salvia

Reputation: 53329

No it's not. You can wrap your call in a with statement to ensure the file closes automatically:

with open('status_grid','a') as myfile:
   subprocess.call(cmd, stdout=myfile, cwd = folder)

Note: with current CPython implementations based on reference counting, the file will be closed when the reference count reaches 0, which will happen immediately in the code you posted. However, this is just an implementation detail of CPython. Other implementations may leave the file open indefinitely. Use the with statement to ensure you've written portable code.

Upvotes: 1

ely
ely

Reputation: 77484

One way to be sure is

with open('status_grid', 'a') as my_file:
    subprocess.call(cmd, stdout=my_file, cwd = folder)

Upvotes: 3

Related Questions