Suite

Python se bloque avec l'objet bande gdal renvoyé à partir d'une fonction


J'ai écrit ces deux fonctions dans un module lorsque je veux lire la bande dans des fichiers NetCDF ou HDF et renvoyer la bande en dehors de la fonction. Chaque HDF et NetCDF possède de nombreux sous-ensembles de données. Chaque sous-ensemble de données dans un fichier NetCDF a 365 bandes tandis que le sous-ensemble de données HDF n'a qu'une seule bande. Lorsque je lance readFile1, il n'y a pas de problème. Cependant, lorsque j'exécute readFile2 et renvoie la bande, je tape out.GetNoDataValue() (ou d'autres fonctions qui lui sont attachées) sur l'interpréteur ou dans une autre fonction, python se bloque. Dans la fonction readFile1, out.GetNoDataValue() ne renvoie aucune valeur de données de la bande avec succès. Lorsque vous retournez le groupe comme dans readFile2, vous ne pouvez rien faire avec. Lorsque vous le faites, python se bloque.

ma version de gdal est '1100000' (gdal.VersionInfo()) Mon système d'exploitation us ubuntu 12.04 LTS

Je pense que cela pourrait être un bug dans gdal, je n'en suis pas sûr.

depuis osgeo import gdal def readFile1(inputFile,variableNo,bandNo): filereadtemp=gdal.Open(inputFile) fileread=gdal.Open(filereadtemp.GetSubDatasets()[variableNo][0]) out=fileread.GetRasterBand(bandNo) nodatavalue= out.GetNoDataValue() return nodatavalue def readFile2(inputFile,variableNo,bandNo): filereadtemp=gdal.Open(inputFile) fileread=gdal.Open(filereadtemp.GetSubDatasets()[variableNo][0]) out=fileread.GetRasterBand(bandNo ) repartir

L'ensemble de données est déréférencé lorsque vous ne retournez que la bande de votre fonction.

La solution consiste à renvoyer l'ensemble de données à partir de votre fonction.

À partir de la page GDAL Python Gotchas :

Python plante si vous utilisez un objet après avoir supprimé un objet avec lequel il a une relation

Considérez cet exemple :

depuis osgeo import gdal dataset = gdal.Open('C:RandomData.img') band = dataset.GetRasterBand(1) print band.Checksum() 31212

Dans cet exemple, la bande a une relation avec l'ensemble de données qui nécessite que l'ensemble de données reste alloué pour que la bande fonctionne. Si nous supprimons l'ensemble de données puis essayons d'utiliser band, Python plantera :

from osgeo import gdal dataset = gdal.Open('C:RandomData.img') band = dataset.GetRasterBand(1) del dataset # Cela amènera le ramasse-miettes Python à désallouer l'ensemble de données band.GetChecksum() # Cela va maintenant crash Python car l'ensemble de données du groupe a disparu < Python plante >

Ce problème peut se manifester de manière subtile. Par exemple, cela peut se produire si vous essayez d'instancier une instance d'ensemble de données temporaire dans une seule ligne de code :

depuis osgeo import gdal print gdal.Open('C:RandomData.img').GetRasterBand(1).Checksum() < Python plante >

Dans cet exemple, l'instance de l'ensemble de données n'était plus nécessaire après l'appel à GetRasterBand(), Python l'a donc désallouée avant d'appeler Checksum().

Ce problème se produit car les objets GDAL et OGR sont implémentés en C++ et les relations entre eux sont maintenues en C++ à l'aide de pointeurs. Lorsque vous supprimez l'instance de l'ensemble de données dans Python, l'objet C++ qui se trouve derrière est désalloué. Mais l'objet C++ derrière l'instance de bande ne sait pas que cela s'est produit, il contient donc un pointeur vers l'objet ensemble de données C++ qui n'existe plus. Lorsque la bande essaie d'accéder à l'objet inexistant, le processus se bloque.

L'équipe GDAL sait que cette conception n'est pas ce que les programmeurs Python attendent. Malheureusement, le design est difficile à corriger, il est donc probable qu'il le reste pendant un certain temps.