Verwirrungsverhalten mit H5Py -Objekt als Instanzvariable
Frage
Ich verwende H5PY, um auf HDF5 -Dateien zuzugreifen und die H5PY -Dateiobjekte in einer Klasse zu speichern. Aber ich habe ein seltsames Verhalten, wenn ich versucht habe, eine geschlossene H5PY -Dateiinstanzvariable mit einer neuen zuzuweisen:
class MyClass:
def __init__(self, filename):
self.h5file = None
self.filename = filename
def vartest(self):
self.h5file = h5py.File(self.filename, 'r')
print self.h5file
self.h5file.close()
print self.h5file
newh5file = h5py.File(self.filename, 'r')
print newh5file
self.h5file = newh5file
print self.h5file
print newh5file
def main():
filename = sys.argv[1]
mycls = MyClass(filename)
mycls.vartest()
Ausgabe:
<HDF5 file "test.h5" (mode r, 92.7M)>
<Closed HDF5 file>
<HDF5 file "test.h5" (mode r, 92.7M)>
<Closed HDF5 file>
<Closed HDF5 file>
Der Versuch, die Instanzvariable mit dem neu geöffneten H5PY -Dateiobjekt zu aktualisieren, scheint den Status des Objekts irgendwie beeinflusst zu haben und ihn zu schließen. Unabhängig von der Implementierung auf der H5Py -Seite sehe ich nicht, wie dieses Verhalten durch mein Verständnis der Python -Sprache sinnvoll ist (dh keine Überlastung des Zuweisungsbetreibers).
Dieses Beispiel wird mit Python 2.6.5 und H5Py 1.3.0 ausgeführt. Wenn Sie dieses Beispiel ausprobieren möchten, aber keine HDF5 -Datei in der Nähe haben, können Sie einfach den Dateizugriffsmodus von 'R' auf 'a' ändern.
Lösung
Ja, dies ist ein bekannter Fehler in H5Py 1.3, der angezeigt wird, wenn Sie HDF5 1.8.5 oder neuer verwenden. Es bezieht sich auf Veränderungen in der Art und Weise, wie die Kennungen in 1.8.5 behandelt werden. Sie können es mithilfe von HDF5 1.8.4 oder früher oder durch Upgrade auf H5PY 2.0 beheben.
Andere Tipps
Ich bin mir nicht sicher, ob dies hilfreich ist, aber wenn ich den Quellcode durchsuche, fand ich dies (abgekürzt):
class HLObject(object):
def __nonzero__(self):
register_thread()
return self.id.__nonzero__()
class Group(HLObject, _DictCompat):
...
class File(Group):
def __repr__(self):
register_thread()
if not self:
return "<Closed HDF5 file>"
return '<HDF5 file "%s" (mode %s, %s)>' % \
(os.path.basename(self.filename), self.mode,
_extras.sizestring(self.fid.get_filesize()))
Weil es kein ... gibt __str__
Methode, __repr__
wird aufgerufen, um die Ausgabe zu produzieren, und __repr__
Erste Anrufe register_thread()
, dann überprüfen Sie, ob Sie feststellen, ob self
ist lebendig (besser bekannt als Bewertung für wahr oder falsch).
Python sucht dann die Klassen, bis sie findet __nonzero__
(was wieder aufruft register_thread()
), dann kehrt zurück self.id.__nonzero__()
, was anscheinend falsch zurückkehrt.
Sie haben also Recht, dass das Problem nicht mit der Namensbindung (Zuordnung) liegt, sondern warum register_thread
und/oder self.id
Bombardiert dich, ich weiß es nicht.