又一个对象序列化程序
yasoo的Python项目详细描述
yasoo
:序列化您拥有的数据
不依赖类型提示的attrs
和dataclass
对象的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
将导致所有非{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'}
- 项目
标签: