NpzFile 在用作上下文管理器时是否关闭自身?



numpy.load()的文档字符串中,我发现了以下警告:

对于.npz文件,必须关闭返回的 NpzFile 类实例以避免泄漏文件描述符。

我注意到,返回的NpzFile对象同时具有__enter__()__exit__()方法。

如果我像这样使用它,它会自动关闭它吗:

>>> with numpy.load('my_mile.npz') as data:
...     A = data['A']

是的。使用with语句将关闭类似文件的对象。下面是一个直接来自文档的示例:

with load('foo.npz') as data:
a = data['a']

简答题

是的,它会在上下文结束后自动关闭文件对象,因为 NpzFile 对象同时具有__enter__()__exit__()方法(请参阅此处(。


长答案

关闭with expression as var上下文管理器的作用域后,var仍保留为上下文管理器外部的对象。但是,numpy.load()的情况下,文件描述符var不能在上下文管理器的范围之外访问。请考虑以下示例:

# Creating a dictionary of data to be saved using numpy.savez
data_dict = {'some_string': 'StackOverflow',
'some_integer': 10000,
'some_array': numpy.array([0,1,2,3,4])
}
# Saving the data
numpy.savez(file='./data_dict.npz', **data_dict)
# Loading the 'data_dict' using context manager
with numpy.load('data_dict.npz') as dt:
string_ = dt['some_string']
integer_ = dt['some_integer']
array_ = dt['some_array']
# OR
with numpy.load('data_dict.npz') as dt:
dt_ = dict(dt) # if you want the entire dictionary to be loaded as is

如果您现在尝试在上下文管理器外部访问文件描述符,它将只返回 NpzFile 对象及其内存地址,如下所示:

>>> dt
Out[]: <numpy.lib.npyio.NpzFile at 0x7ffba63bb7c0>

但是,正如预期的那样,您将无法访问其任何属性或属性。例如,当您执行以下操作时,您会得到AttributeError

>>> dt['some_string']
Out[]: Traceback (most recent call last):
.
.
File ".../site-packages/numpy/lib/npyio.py", line 249, in __getitem__
bytes = self.zip.open(key)
AttributeError: 'NoneType' object has no attribute 'open'

这是因为,在 with 上下文管理器结束后,NpzFile 对象的self.zip变量被分配None值(请参阅上面第一个 URL 中的def close(self):,该 URL 在 dunder__exit__()中被调用(

注意 1:dt.keys()返回(如预期的那样(一个 KeysView 对象,执行list(dt.keys())会为您提供dt的键名称列表:['some_string', 'some_integer', 'some_array']。但是,仍然无法访问存储在这些键上的值(在上下文管理器的作用域之外((在上下文管理器的作用域内(。

注 2:我特意使用了包含非 numpy 数组的字典,只是为了表明可以使用numpy.savez()来存储此类字典。但是,这不是存储此类数据的推荐方法。

相关内容

  • 没有找到相关文章

最新更新