简体   繁体   English

使用h5py对象作为实例变量来复制赋值行为

[英]Perplexing assignment behavior with h5py object as instance variable

I'm using h5py to access HDF5 files and store the h5py File objects in a class. 我正在使用h5py访问HDF5文件并将h5py File对象存储在类中。 But I'm experiencing some strange behavior in attempting to reassign a closed h5py file instance variable with a new one: 但是我试图用一个新的重新分配一个封闭的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()

Output: 输出:

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

Attempting to update the instance variable with the newly opened h5py File object appears to have somehow affected the state of the object, closing it. 尝试使用新打开的h5py File对象更新实例变量似乎以某种方式影响了对象的状态,关闭它。 Regardless of the implementation on the h5py side, I don't see how this behavior makes sense from my understanding of the Python language (ie, no overloading of the assignment operator). 无论h5py方面的实现如何,我都没有看到这种行为对我的Python语言的理解是有意义的(即,没有赋值运算符的重载)。

This example is run with Python 2.6.5 and h5py 1.3.0. 此示例使用Python 2.6.5和h5py 1.3.0运行。 If you want to try this example but don't have an HDF5 file sitting around you can just change the file access mode from 'r' to 'a'. 如果你想尝试这个例子,但没有HDF5文件,你只需将文件访问模式从'r'更改为'a'即可。

Not sure if this will help, but searching through the source code I found this (abbreviated): 不确定这是否有帮助,但搜索源代码我发现这个(缩写):

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

Because there is no __str__ method, __repr__ is called to produce the output, and __repr__ first calls register_thread() , then checks to see if self is alive (better known as evaluating to True or False). 因为没有__str__方法, __repr__调用__repr__来产生输出, __repr__首先调用register_thread() ,然后检查self是否存活(更好地称为评估为True或False)。

Python then searches the classes until it finds __nonzero__ (which again calls register_thread() ), then returns self.id.__nonzero__() , which is apparently returning False. 然后Python搜索类,直到它找到__nonzero__ (再次调用register_thread() ),然后返回self.id.__nonzero__() ,这显然返回False。

So, you are correct in that the issue is not with the name binding (assignment), but why register_thread and/or self.id is bombing out on you, I do not know. 所以,你是正确的,因为问题不在于名称绑定(赋值),而是为什么register_thread和/或self.id正在轰炸你,我不知道。

Yes, this is a known bug in h5py 1.3, which shows up when you use HDF5 1.8.5 or newer. 是的,这是h5py 1.3中的已知错误,当​​您使用HDF5 1.8.5或更高版本时会显示该错误。 It's related to changes in the way identifiers are handled in 1.8.5. 它与1.8.5中标识符处理方式的变化有关。 You can fix it by using HDF5 1.8.4 or earlier, or by upgrading to h5py 2.0. 您可以使用HDF5 1.8.4或更早版本或升级到h5py 2.0来修复它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM