Comportamiento de asignación desconcertante con objeto H5PY como variable de instancia

StackOverflow https://stackoverflow.com/questions/7355545

  •  28-10-2019
  •  | 
  •  

Pregunta

Estoy usando H5PY para acceder a los archivos HDF5 y almacenar los objetos del archivo H5PY en una clase. Pero estoy experimentando un comportamiento extraño al intentar reasignar una variable de instancia de archivo H5PY cerrada con una nueva:

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()

Producción:

<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>

Intentar actualizar la variable de instancia con el objeto de archivo H5PY recién abierto parece haber afectado de alguna manera el estado del objeto, cerrándola. Independientemente de la implementación en el lado H5PY, no veo cómo este comportamiento tiene sentido a mi comprensión del lenguaje de Python (es decir, sin sobrecarga del operador de tarea).

Este ejemplo se ejecuta con Python 2.6.5 y H5Py 1.3.0. Si desea probar este ejemplo, pero no tiene un archivo HDF5 sentado, puede cambiar el modo de acceso al archivo de 'R' a 'A'.

¿Fue útil?

Solución

Sí, este es un error conocido en H5PY 1.3, que aparece cuando usa HDF5 1.8.5 o más nuevo. Está relacionado con los cambios en la forma en que se manejan los identificadores en 1.8.5. Puede solucionarlo usando HDF5 1.8.4 o anterior, o actualizando a H5PY 2.0.

Otros consejos

No estoy seguro de si esto ayudará, pero la búsqueda a través del código fuente encontré esto (abreviado):

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()))

Porque no hay __str__ método, __repr__ está llamado a producir la salida y __repr__ Primeras llamadas register_thread(), luego verifica para ver si self está vivo (mejor conocido como evaluación de verdadero o falso).

Python luego busca en las clases hasta que encuentre __nonzero__ (que vuelve a llamar register_thread()), luego regresa self.id.__nonzero__(), que aparentemente está volviendo falso.

Entonces, tiene razón en que el problema no es con el nombre vinculante (asignación), sino por qué register_thread y/o self.id te está bombardeando, no lo sé.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top