如何确保 netcdf 文件在 python 中关闭?

How to make sure a netcdf file is closed in python?

可能很简单,但我一直无法在网上找到解决方案... 我正在尝试使用存储为 netcdf 文件的一系列数据集。我打开每一个,阅读一些关键点,然后转到下一个文件。我发现我经常点击 mmap errors/the 随着更多文件被读入,脚本速度变慢。我相信这可能是因为 .close() 命令没有正确关闭 netcdf 文件。

我一直在测试这个:

from scipy.io.netcdf import netcdf_file as ncfile
f=ncfile(netcdf_file,mode='r')
f.close()

那如果我试试

>>>f
<scipy.io.netcdf.netcdf_file object at 0x24d29e10>

>>>f.variables['temperature'][:]
array([ 1234.68034431,  1387.43136567,  1528.35794546, ...,  3393.91061952,
    3378.2844357 ,  3433.06715226])

所以文件似乎仍然打开? close() 实际上做了什么?我怎么知道它起作用了? 有没有办法从 python 中 close/clear 所有打开的文件?

软件: Python 2.7.6,scipy 0.13.2,netcdf 4.0.1

f.close 的代码是:

Definition: f.close(self)
Source:
    def close(self):
        """Closes the NetCDF file."""
        if not self.fp.closed:
            try:
                self.flush()
            finally:
                self.fp.close()

f.fp 是文件对象。所以

In [451]: f.fp
Out[451]: <open file 'test.cdf', mode 'wb' at 0x939df40>

In [452]: f.close()

In [453]: f.fp
Out[453]: <closed file 'test.cdf', mode 'wb' at 0x939df40>

但我通过使用 f 发现我仍然可以创建维度和变量。但是f.flush()returns出错了

它看起来不像是在数据写入期间使用 mmap,只是在读取期间使用。

def _read_var_array(self):
            ....
            if self.use_mmap:
                mm = mmap(self.fp.fileno(), begin_+a_size, access=ACCESS_READ)
                data = ndarray.__new__(ndarray, shape, dtype=dtype_,
                        buffer=mm, offset=begin_, order=0)
            else:
                pos = self.fp.tell()
                self.fp.seek(begin_)
                data = fromstring(self.fp.read(a_size), dtype=dtype_)
                data.shape = shape
                self.fp.seek(pos)

我对 mmap 没有太多经验。看起来它基于文件中的字节块设置了一个 mmap 对象,并将其用作变量的数据缓冲区。如果基础文件关闭,我不知道该访问会发生什么。如果出现某种 mmap 错误,我不会感到惊讶。

如果文件是用 mmap=False 打开的,那么整个变量被读入内存,并像常规 numpy 数组一样访问。

mmap : None or bool, optional
    Whether to mmap `filename` when reading.  Default is True
    when `filename` is a file name, False when `filename` is a
    file-like object

我的猜测是,如果您在未指定 mmap 模式的情况下打开一个文件,从中读取一个变量,然后关闭该文件,那么稍后引用该变量及其数据是不安全的。任何需要加载更多数据的引用都可能导致 mmap 错误。

但是,如果您使用 mmap=False 打开文件,即使在关闭文件后,您也应该能够切片变量。

我看不出一个文件或变量的 mmap 会如何干扰对其他文件和变量的访问。但我必须阅读更多关于 mmap 的内容才能确定这一点。

来自 netcdf 文档:

Note that when netcdf_file is used to open a file with mmap=True (default for read-only), arrays returned by it refer to data directly on the disk. The file should not be closed, and cannot be cleanly closed when asked, if such arrays are alive. You may want to copy data arrays obtained from mmapped Netcdf file if they are to be processed after the file is closed, see the example below.