首页 > 解决方案 > 如何用自定义类替换 h5py.AttributeManager?

问题描述

我想将 astropy 存储Quantity在 hdf5 属性中。

我现在正在做的是这样的:

from astropy import units
import h5py


length_1 = 5.3 * units.meter

# -- Write attribute ----------
with h5py.File("./temp.hdf5", "w") as data:
    # write value
    data.attrs.create("length", length_1.value)
    # write unit  
    data.attrs.create("lengthUnit", length_1.unit.to_string())

# -- Read attribute -----------
with h5py.File("./temp.hdf5", "r") as data:
    # read value
    lengthValue = data.attrs["length"]
    # read unit
    lengthUnit = data.attrs["lengthUnit"]

    # recreate length as Quantity
    length_2 = lengthValue * units.Unit(lengthUnit)

但是,如果我可以修改 getter/setter 进程以像我在这里所做的那样AttributeManager处理任何内容,那将会很有帮助。Quantity例如

class QuantityAttributeManager(h5py.AttributeManager):

    def __init__(self, parent):
        super().__init__(parent)

    # __setitem__ uses create
    def create(self, name, data, shape=None, dtype=None):

        if isinstance(data, units.Quantity):
            super().create(
                    name,
                    data.value
                    )
            super().create(
                    "{:s}Unit".format(name),
                    data.unit.to_string().encode("utf-8")
                    )
        else:
            super().create(name, data, shape, dtype)

    # def __getitem__

    # [...]

with h5py.File("./temp.hdf5", "w") as data:
    # really this should be:
    #    data.attrs["length"] = length
    # and this is where the problem lies
    attr = QuantityAttributeManager(data["/"])
    attr["length"] = length_1

    print(list(attr.keys()))  # ['length', 'lengthUnit']

.attrs属性定义为 ( [source] )

@property
def attrs(self):
    """ Attributes attached to this object """
    from . import attrs
    with phil:
        return attrs.AttributeManager(self)

HLObject,其中DatasetGroup继承。File继承Group但覆盖.attrs.

我能看到的最佳选择是重定向from . import attrs线路以使用QuantityAttributeManager,但我不确定如何。(最好不要太老套。)

标签: python-3.xh5py

解决方案


一个可能的解决方案是猴子补丁,但新的属性管理器总是会被使用。

h5py._hl.attrs.AttributeManager = QuantityAttributeManager

with h5py.File("./temp.hdf5", "w") as data:
    data.attrs["length"] = length

    print(list(data.attrs.keys()))  # ['length', 'lengthUnit']

推荐阅读