Can anyone shed some light on why this example works:
import numpy as np
def write_data(fn, var):
with open(fn, 'wb') as fout:
header = 'TEST\n'
np.savetxt(fout, var, fmt='%.2f', header=header, delimiter=' ', comments='')
data = np.asarray([[1.0, 2.0], [3.0, 4.0]])
out_file = 'out/test.txt'
write_data(out_file, data)
But it stops working if you change write_data
to:
def write_data(fn, var):
fout = open(fn, 'wb')
header = 'TEST\n'
np.savetxt(fout, var, fmt='%.2f', header=header, delimiter=' ', comments='')
I would not want to write the code as shown below, but someone came to me asking why this code does not work and I simply have no answer for them. In the top case, a file is written with the expected header and data, but in the bottom case, a file is created, but it is empty. No errors are reported, no exceptions are thrown.
Oddly, in the original case (which was much longer), printing the var
would also cause the non-with
example to start working, which makes me think this may be a timing issue, as printing the var
in the example as shown makes no difference on my machine.
It's been pointed out that both these examples also fix the issue:
def write_data(fn, var):
fout = open(fn, 'wb')
header = 'TEST\n'
np.savetxt(fout, var, fmt='%.2f', header=header, delimiter=' ', comments='')
fout.close()
def write_data(fn, var):
fout = open(fn, 'wb', buffering=0)
header = 'TEST\n'
np.savetxt(fout, var, fmt='%.2f', header=header, delimiter=' ', comments='')
But that serves to narrow down the question to: why does Python not flush file handles that are dereferenced and what causes a file buffer to get flushed, since apparently performing some other operation can cause this to happen automatically?
For example, the example below caused the problem to get 'solved', or rather circumvented in the original problem as it was brought to me (with a lot of added code not relevant to the problem).
def write_data(fn, var):
fout = open(fn, 'wb')
header = 'TEST\n'
print(var)
np.savetxt(fout, var, fmt='%.2f', header=header, delimiter=' ', comments='')