又一个对象序列化程序

yasoo的Python项目详细描述


yasoo:序列化您拥有的数据

Build StatuscodecovLicense: MITCode style: black

不依赖类型提示的attrsdataclass对象的python序列化程序。在

为什么是yasoo

yasoo将类型数据添加到序列化数据中,因此反序列化不需要依赖类型提示。在

此外,如果您有一个可以包含多种类型值的字段,或者一个包含抽象类的某些特定实现的字段,yasoo对此没有任何问题。在

例如,此代码可以正常工作:

from attr import attrs, attrib
from yasoo import serialize, deserialize

@attrs
class Foo:
    a = attrib()

@attrs
class Bar:
    foo: Foo = attrib()

serialized = serialize(Bar(foo=5))
assert(deserialize(serialized).foo == 5)

使用

基本用法

对于简单对象,请使用:

^{pr2}$

高级用法

反序列化对象集合

可以反序列化对象集合:

from attr import attrs, attrib
from yasoo import serialize, deserialize
from yasoo.typing import List_

@attrs
class Foo:
    a = attrib()

foos = [Foo(a=i) for i in range(5)]
serialized = serialize(foos)
de_foos = deserialize(serialized, obj_type=List_[Foo])
assert de_foos == foos

请注意,将对象类型作为List[Foo]传递不会给您该类型 ,但使用de_foos将修复此问题。在

自定义(反)序列化程序

对于需要自定义序列化/反序列化的对象,可以注册自己的方法:

from attr import attrs, attrib, asdict
from yasoo import serialize, deserialize, serializer, deserializer

@attrs
class Foo:
    bar = attrib(converter=lambda x: x * 2)

    def set_foobar(self, foobar):
        self.foobar = foobar

    @serializer
    def serialize(self: 'Foo'):
        result = asdict(self)
        if hasattr(self, 'foobar'):
            result['foobar'] = self.foobar
        return result

    @staticmethod
    @deserializer
    def deserialize(data: dict) -> 'Foo':
        foo = Foo(data['bar'] / 2)
        if 'foobar' in data:
            foo.set_foobar(data['foobar'])
        return foo

注意,注册带有前向引用的自定义方法(即'Foo'而不是Foo)需要将globals参数传递给serialize/deserialize,例如

serialize(obj, globals=globals())

使用类型提示

如果要避免在序列化数据中使用__type键,可以在调用serialize时将type_key参数设置为None。在

要使其正常工作,序列化类中不可json序列化的所有字段都应具有类型提示。在

序列化序列

默认情况下,在序列化过程中,数据中找到的所有序列都将转换为list。 如果您想将它们反序列化为列表以外的任何内容,请在调用serialize时将preserve_iterable_types参数设置为True。在

注意:将preserve_iterable_types参数设置为True将导致所有非{}的iterable序列化为字典,其类型保存在type_key下。在

同一类型的多个序列化方法

如果要为特定用例的类型定义自定义序列化方法,而不影响默认序列化程序,则可以创建Serializer的另一个实例,并在该实例上注册该方法。例如:

from yasoo import Serializer, serializer, serialize

@serializer
def serialize_foo(foo: Foo):
    return {'bar': foo.bar}

my_serializer = Serializer()

@my_serializer.register()
def serialize_foo_another_way(foo: Foo):
    return {'bar': foo.bar * 2}

serialize(Foo(bar=5))  # returns {'bar': 5, '__type': 'Foo'}
my_serializer.serialize(Foo(bar=5))  # returns {'bar': 10, '__type': 'Foo'}

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java从Dropwizard中的Minio检索文件时,GET请求中的超时是如何处理的?   带Hibernate的java Jackson用于序列化以避免枚举   Raspberry Pi上的java Jave分段错误   java在屏幕旋转时不保存当前片段和数据   java War文件未在Heroku上正确部署   如何使用Java处理Selenium webdriver中的促销广告或cookie   java处理“用法:PApplet[options]<classname>[sketch args]”   java文本文件错误扫描程序   运行第一个JavaFX模块化程序时出现java异常   java将fileoutputstream转换为字符串   如何调试gstreamerjava?   java Spring RestTemplate ResponseBody类是什么样的   如何将JSON数组转换为Java列表。我在用斯文森   javascript在显示div按钮后进入新页面