3

我正在使用 h5py 访问 HDF5 文件并将 h5py 文件对象存储在一个类中。但是我在尝试用一个新的重新分配一个封闭的 h5py 文件实例变量时遇到了一些奇怪的行为:

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

输出:

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

尝试使用新打开的 h5py File 对象更新实例变量似乎以某种方式影响了对象的状态,将其关闭。不管 h5py 方面的实现如何,从我对 Python 语言的理解来看,我看不出这种行为有什么意义(即没有重载赋值运算符)。

此示例使用 Python 2.6.5 和 h5py 1.3.0 运行。如果您想尝试此示例但没有 HDF5 文件,您可以将文件访问模式从“r”更改为“a”。

4

2 回答 2

1

不确定这是否有帮助,但通过源代码搜索我发现了这个(缩写):

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

因为没有__str__方法,__repr__被调用来产生输出,并且__repr__首先调用register_thread(),然后检查是否self存活(更好地称为评估为 True 或 False)。

Python 然后搜索类,直到找到__nonzero__(它再次调用register_thread()),然后返回self.id.__nonzero__(),这显然返回 False。

所以,你是对的,问题不在于名称绑定(分配),而是为什么register_thread和/或self.id正在轰炸你,我不知道。

于 2011-09-09T00:16:18.623 回答
1

是的,这是 h5py 1.3 中的一个已知错误,当​​您使用 HDF5 1.8.5 或更高版本时会出现。它与 1.8.5 中处理标识符的方式的变化有关。您可以使用 HDF5 1.8.4 或更早版本或升级到 h5py 2.0 来修复它。

于 2011-09-09T22:22:42.307 回答