gpt4 book ai didi

python - 使用 with 语句关闭 GDAL 数据集

转载 作者:行者123 更新时间:2023-11-28 22:19:33 37 4
gpt4 key购买 nike

考虑这个使用来自 Jeff Knupp's blogwith 语句的基本示例:

class File():

def __init__(self, filename, mode):
self.filename = filename
self.mode = mode

def __enter__(self):
self.open_file = open(self.filename, self.mode)
return self.open_file

def __exit__(self, *args):
self.open_file.close()

我有一个测试文件,其中包含两行,“ABC”和“DEF”。一切都按预期工作:

with File('/tmp/testfile','r') as f:
txt = [x.strip() for x in f.readlines()]
print(txt)

# ['ABC', 'DEF']

with block 之外调用类方法会给我预期的错误:

f.readlines()

ValueError Traceback (most recent call last) in () ----> 1 f.readlines()

ValueError: I/O operation on closed file.


现在回答我的问题:

如何使用 gdal 对象而不是文件实现相同的行为?

我有一个类方法,它应该从磁盘读取数据并将其放入 gdal 栅格中以供进一步处理。完成后,我想适本地关闭生成的 gdal 光栅。通常这是通过将其设置为 None 并使用 gdal.Unlink 来完成的。

但是,当我像前面的示例一样将所有内容都放入上下文结构中时,我仍然可以在 with block 之外与数据集进行交互。

这是一个可重现的例子:

class Raster:
'''Raster class with sidelength s'''
def __init__(self,s):
self.sidelength = s

def __enter__(self):
# create raster in memory
driver = gdal.GetDriverByName('GTiff')
self.raster = driver.Create('/vsimem/inmem.tif', self.sidelength, self.sidelength, 1, gdal.GDT_Float32)
self.raster.GetRasterBand(1).WriteArray(np.random.rand(self.sidelength,self.sidelength))
return self.raster

def __exit__(self, *args):
# close file and unlink
self.raster = None
gdal.Unlink('/vsimem/inmem.tif')

with block 按预期工作:

with Raster(5) as r:
print(r)

# <osgeo.gdal.Dataset; proxy of <Swig Object of type 'GDALDatasetShadow *' at 0x7f8078862ae0> >

但是在 block 之后对象仍然存在,我仍然可以读取值:

print(r)

#<osgeo.gdal.Dataset; proxy of <Swig Object of type 'GDALDatasetShadow *' at 0x7f8078044a20> >

print(r.ReadAsArray())

#[[0.2549882 0.80292517 0.23358545 0.6284887 0.7294142 ]
# [0.9310723 0.21535267 0.9054575 0.60967094 0.9937953 ]
# [0.69144976 0.01727938 0.16800325 0.61249655 0.1785022 ]
# [0.16179436 0.43245795 0.7042811 0.4809799 0.85534436]
# [0.67751276 0.7560658 0.9594516 0.6294476 0.3539126 ]]

最佳答案

您不能在保留对 gdal 数据集的引用的同时真正关闭它。您可以改为保留对 Raster 实例的引用,并使用 r.raster 访问 with block 内的数据集。

class Raster:
'''Raster class with sidelength s'''
def __init__(self,s):
self.sidelength = s

def __enter__(self):
# create raster in memory
driver = gdal.GetDriverByName('GTiff')
self.raster = driver.Create('/vsimem/inmem.tif', self.sidelength, self.sidelength, 1, gdal.GDT_Float32)
self.raster.GetRasterBand(1).WriteArray(np.random.rand(self.sidelength,self.sidelength))
return self

def __exit__(self, *args):
# close file and unlink
self.raster = None
gdal.Unlink('/vsimem/inmem.tif')


with Raster(5) as r:
print(r.raster)

输出:

<osgeo.gdal.Dataset; proxy of <Swig Object of type 'GDALDatasetShadow *' at 0x04564728> >

with block 之外,数据集无法访问:

r.raster is None

输出:

True

如果您将另一个变量绑定(bind)到 r.raster 会再次出现问题,因此您可能希望将它与您需要的任何功能一起完全封装在 Raster 实例中.在这一点上,您或多或少会重新发明 Rasterio,但如果您的需求很简单,那可能比依赖它更好。

关于python - 使用 with 语句关闭 GDAL 数据集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49648360/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com