跳转到主要内容

一个简单的装饰器,使您的类可序列化

项目描述

https://codecov.io/gh/steven-murray/hickleable/branch/main/graph/badge.svg?token=7TRaE5cJzZ PyPI - License https://img.shields.io/badge/code%20style-black-000000.svg Documentation Status

一个简单的装饰器,使您的类可序列化。

这是什么?

hickleable 为您的类提供了一个简单的装饰器,它几乎总是使用出色的 hickle 包将它们序列化。默认情况下,hickle 不支持自定义类——相反,它们被写入HDF5文件作为二进制数据集,使用标准的Python pickle 进行序列化。这显然抵消了hickle 的许多好处,例如,pickle序列化的数据只能用Python读取。

hickle 通过定义一些加载/卸载钩子提供了一种序列化自定义类的方法,使用HDF5格式。但是,由于它们相当通用,实现这些钩子可能有点棘手。

hickleable 提供了这些钩子的“默认实现”,应该能满足大多数自定义类的需求,并且可以作为一个简单的装饰器应用。这使得将您的类转换为支持的 数据格式 变得非常简单。

请参阅 ReadTheDocs 中的文档。

安装

只需 pip install 可序列化。可用的conda安装依赖项包括 h5py

用法

只需

from hickleable import hickleable

@hickleable()
class MyClass:
   def __init__(self, a=1, b='foo', c={'a': 'dict'}):
       self.a = a
       self.b = b
       self.c = c

现在,MyClass 可以在不进行任何pickle的情况下进行hickle序列化

import hickle

my_obj = MyClass()
hickle.dump(my_obj, 'temporary_file.h5')  # Note: no warnings about having to pickle
new_obj = hickle.load('temporary_file.h5')

一个超级酷的事情是,它尊重@cached_property 属性,并且也支持dataclasses

from dataclass import dataclass
from functools import cached_property

@hickleable()
@dataclass
class CachedClass:
    foo: str
    bar: int

    @cached_property
    def foobar(self) -> str:
        print("Obtaining foobar...")
        return foo*bar

c = CachedClass('baz', 50000)

foobar = c.foobar  # prints "Obtaining foobar..."
foobar = c.foobar  # prints nothing, since it's returning cached value.

hickle.dump(c, 'foobar.h5')
d = hickle.load('foobar.h5')

d_foobar = d.foobar  # prints nothing! The value is cached in the hickle file.

需要注意的一点是,只有已经评估过的缓存属性才会被保存在hickle文件中。要强制将所有缓存属性写入文件,请在调用()时使用参数。

自定义导出/加载

虽然会自动将大多数类转换为hickle-able,但在某些情况下,构成属性本身可能不是hickle-able,或者您可能希望自定义其他方面。虽然所有这些都完全可以使用的导出/加载钩子来自定义,但装饰器也尊重<__gethstate__>和<__sethstate__>魔法方法,它们的作用与pickle中的<__getstate__>和<__setstate__>相同。事实上,如果后者存在而前者不存在,则后者将用于在中序列化对象。例如,假设您有一个在其生命周期中跟踪被调用次数的类

@hickleable()
class Counter:
    def __init__(self, a):
        self.a = a
        self._counts = 0

    def __call__(self, b):
        self._counts += 1
        self.a *= b

如果我们创建一个实例并多次调用它,_counts属性将大于零。如果我们将对象保存到hickle文件并在其他地方重新加载它,它将 _counts > 0开始。我们可以如下避免这种情况

def ignore_counts(self, state: dict):
    state['_counts'] = 0
    self.__dict__.update(state)

Counter.__setstate__ = ignore_counts

我们也可以从hickle文件中完全删除_counts

def remove_counts(self) -> dict:
    return {k: v for k, v in self.__dict__.items() if k != '_counts'}

Counter.__gethstate__ = remove_counts

请注意,由于我们将ignore_counts设置为__setstate__方法,它将被和pickle双方尊重。我们将remove_counts设置为__gethstate__方法,这意味着它只被尊重。

项目详情


下载文件

下载适用于您的平台的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。

源代码分发

hickleable-0.2.4.tar.gz (22.6 kB 查看哈希值)

上传时间 源代码

构建分发

hickleable-0.2.4-py2.py3-none-any.whl (7.5 kB 查看哈希值)

上传时间 Python 2 Python 3

由以下支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误记录 StatusPage StatusPage 状态页面