3

h5py を使用して HDF5 ファイルにアクセスし、h5py File オブジェクトをクラスに格納しています。しかし、閉じた 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

はい、これは h5py 1.3 の既知のバグで、HDF5 1.8.5 以降を使用すると表示されます。これは、1.8.5 での識別子の処理方法の変更に関連しています。HDF5 1.8.4 以前を使用するか、h5py 2.0 にアップグレードすることで修正できます。

于 2011-09-09T22:22:42.307 に答える
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 への評価として知られています)。

__nonzero__次に、Python は(再び を呼び出すregister_thread())が見つかるまでクラスを検索し、self.id.__nonzero__()明らかに False を返す を返します。

したがって、問題は名前のバインディング(割り当て)にあるのではなく、なぜregister_threadおよび/またはself.id爆撃しているのかはわかりません。

于 2011-09-09T00:16:18.623 に答える