Python 为什么'np.savetxt'可以在'with'内部使用文件,而不能在外部使用?

Python 为什么'np.savetxt'可以在'with'内部使用文件,而不能在外部使用?,python,numpy,Python,Numpy,有谁能解释一下这个例子为什么有效: 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

有谁能解释一下这个例子为什么有效:

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)
但如果您将
写入数据
更改为:

def write_data(fn, var):
    fout = open(fn, 'wb')
    header = 'TEST\n'
    np.savetxt(fout, var, fmt='%.2f', header=header, delimiter=' ', comments='')
我不想写下面所示的代码,但是有人来问我为什么这个代码不起作用,我根本没有答案。在顶部情况下,使用预期的头和数据写入文件,但在底部情况下,创建了一个文件,但它是空的。不会报告任何错误,也不会引发任何异常

奇怪的是,在原来的情况下(时间更长),打印
var
也会导致带有
示例的非
开始工作,这使我认为这可能是一个计时问题,因为在所示示例中打印
var
在我的机器上没有任何区别

有人指出,这两个例子也解决了这个问题:

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='')
但这将问题缩小到:为什么Python不刷新被取消引用的文件句柄,是什么导致文件缓冲区被刷新,因为显然执行其他操作会导致自动刷新

例如,下面的示例导致问题得到了“解决”,或者更确切地说,在最初的问题中,它被带到了我的面前(添加了许多与问题无关的代码)


我想您应该关闭打开的文件:

def write_data(fn, var):
    fout = open(fn, 'wb')
    header = 'TEST\n'
    np.savetxt(fout, var, fmt='%.2f', header=header, delimiter=' ', comments='')
    fout.close()

Python缓冲其输出—这意味着如果程序仍在运行,则在关闭或刷新文件之前,可能不会写入输出。(Python尝试在退出时自动优雅地关闭文件,但如果您突然终止程序,例如通过Ctrl-C或类似方式,它可能无法这样做。)脚本结束将被视为突然终止-同样,在循环50多个文件时,结果也是一样的。它们都将被创建,没有一个接收内容,即使脚本运行了大约20秒。缓冲不是基于时间的,而是基于写入了多少内容。@Amber,你有什么线索可以解释为什么在
.savetxt()之前添加一条类似
print(var)
的语句吗
语句会导致内容写入文件和屏幕吗?写入标准的OutCase Python是否也会刷新文件缓冲区,或者类似的东西?写入的数据量似乎不会因此而改变?不知道。这可能是特定Python实现的一些怪癖;也就是说,添加
.close()
与使用
包装
具有相同的效果,这是有意义的,因为Python将在使用
清理
时关闭文件。但是,当不再引用或脚本结束时,Python为什么不刷新已创建和写入的文件的缓冲区呢?似乎为
open()
语句提供
buffering=0
参数也解决了问题,因此显然是底层系统缓冲区造成的。这就把我的问题缩小到为什么Python不会导致取消引用的文件指针刷新它们的缓冲区?这里我接受您的回答,因为它归结为关闭文件以确保刷新缓冲区。严格地说,它没有回答为什么的问题,但它确实把这些点联系了起来。
def write_data(fn, var):
    fout = open(fn, 'wb')
    header = 'TEST\n'
    np.savetxt(fout, var, fmt='%.2f', header=header, delimiter=' ', comments='')
    fout.close()