在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()
来存储此类字典。但是,这不是存储此类数据的推荐方法。