gluonts.core.serde 包#
gluonts.core.serde#
一个简单的序列化/反序列化框架,它使用人类可读的 JSON 编码来表示数据。
在某些方面,它是 pickle 的替代方案,但 serde 不使用二进制编码,而是输出与 JSON 兼容的文本。这主要有两个优点:它是人类可读的,并且编码可以在不同的 Python 版本中工作。
可以直接在 json 中表示的值不会改变,因此对于像 1、["a", "b", "c"] 或 {"foo": "bar"} 这样的值,serde.encode 与 json.dumps 几乎相同。
然而,更复杂的值则以不同的方式编码。对于这些值,我们创建一个使用特殊 __kind__ 属性的对象,该属性可以是以下之一:
class Kind(str, Enum):
Type = "type"
Instance = "instance"
Stateful = "stateful"
类型只是一个类或函数的路径,实例是一个可以通过向其构造函数传递参数来重新构建的对象,而 `stateful` 表示通过在类型的空实例上设置 __dict__ 属性来解码的对象。
serde.encode 使用 functools.singledispatch 来编码给定对象。它针对多种现有类型(例如命名元组、路径和 pydantic.BaseModel)进行了实现。
此外,可以从 serde.Stateful 或 serde.Stateless 派生,以选择其中一种行为。后者要求类支持 pickle 协议中的 __getnewargs_ex__。
要编码自定义值,可以使用 serde.encode.register 装饰器。例如,可以通过以下方式添加对 numpy 数组的支持:
@encode.register(np.ndarray)
def encode_np_ndarray(v: np.ndarray) -> Any:
return {
"__kind__": Kind.Instance,
"class": "numpy.array",
"args": encode([v.tolist(), v.dtype]),
}
对于给定类型,无需实现 decode 方法,因为编码中应该包含如何构建对象的信息。
与 json 类似,serde 不支持对象标识。这意味着如果一个对象在对象图中存在两次,它将在每次出现时被编码。因此,循环引用不起作用。
dump_json 和 load_json 是简单的辅助函数,它们内部使用 encode 和 decode。
- class gluonts.core.serde.Eventual(*args, **kwds)[source]#
基类:
Generic
[gluonts.core.serde._dataclass.T
]- value: gluonts.core.serde._dataclass.T#
- class gluonts.core.serde.OrElse(fn: Callable)[source]#
基类:
object
dataclass 的一个默认字段,它使用一个函数来计算未传递值时的值。
该函数可以接受参数,这些参数是带注解的 dataclass 的其他字段,这些字段也可以是 OrElse 字段。如果出现循环依赖,则会抛出错误。
@serde.dataclass class X: a: int b: int = serde.OrElse(lambda a: a + 1) c: int = serde.OrEsle(lambda c: c * 2) x = X(1) assert x.b == 2 assert x.c == 4
- fn: Callable#
- parameters: dict#
- gluonts.core.serde.dataclass(cls=None, *, init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False)[source]#
serde 的自定义 dataclass 包装器。
这类似于
dataclasses.dataclass
和pydantic.dataclasses.dataclass
装饰器。与pydantic
版本类似,它在运行时执行参数的类型检查。
- gluonts.core.serde.decode(r: Any) Any [source]#
从中间表示 r 解码一个值。
- 参数
r – 要解码的中间表示。
- 返回
一个 Python 数据结构,对应于
r
的解码版本。- 返回类型
Any
另请参阅
encode
逆函数。
- gluonts.core.serde.dump_json(o: Any, indent: Optional[int] = None) str [source]#
将对象序列化为 JSON 字符串。
- 参数
o – 要序列化的对象。
indent – 用作缩进的可选空格数量。
- 返回
表示 JSON 格式对象的字符串。
- 返回类型
str
另请参阅
load_json
逆函数。
- gluonts.core.serde.encode(v: Any) Any [source]#
将值 v 转换为可序列化的中间表示(例如,命名元组被编码为字典)。然后递归遍历该中间表示,并将其序列化为 Python 代码或 JSON 字符串。
此函数使用
singledispatch()
装饰器进行装饰,客户端可以针对基本实现不支持的类型族进行特殊化处理(如下所述)。示例
基本实现所实现的转换逻辑用作备用方案,并通过一系列示例来解释效果最佳。
列表(作为列表)。
>>> encode([1, 2.0, '3']) [1, 2.0, '3']
字典(作为字典)。
>>> encode({'a': 1, 'b': 2.0, 'c': '3'}) {'a': 1, 'b': 2.0, 'c': '3'}
命名元组(作为字典,包含成员
'__kind__': <Kind.Instance: 'instance'>
)。>>> from pprint import pprint >>> from typing import NamedTuple >>> class ComplexNumber(NamedTuple): ... x: float = 0.0 ... y: float = 0.0 >>> pprint(encode(ComplexNumber(4.0, 2.0))) {'__kind__': <Kind.Instance: 'instance'>, 'class': 'gluonts.core.serde._base.ComplexNumber', 'kwargs': {'x': 4.0, 'y': 2.0}}
带有
validated()
初始化器的类(作为字典,包含成员'__kind__': <Kind.Instance: 'instance'>
)。>>> from gluonts.core.component import validated >>> class ComplexNumber: ... @validated() ... def __init__(self, x: float = 0.0, y: float = 0.0) -> None: ... self.x = x ... self.y = y >>> pprint(encode(ComplexNumber(4.0, 2.0))) {'__kind__': <Kind.Instance: 'instance'>, 'args': [], 'class': 'gluonts.core.serde._base.ComplexNumber', 'kwargs': {'x': 4.0, 'y': 2.0}}
带有
__getnewargs_ex__
魔术方法的类(作为字典,包含成员'__kind__': <Kind.Instance: 'instance'>
)。>>> from gluonts.core.component import validated >>> class ComplexNumber: ... def __init__(self, x: float = 0.0, y: float = 0.0) -> None: ... self.x = x ... self.y = y ... def __getnewargs_ex__(self): ... return [], {'x': self.x, 'y': self.y} >>> pprint(encode(ComplexNumber(4.0, 2.0))) {'__kind__': <Kind.Instance: 'instance'>, 'args': [], 'class': 'gluonts.core.serde._base.ComplexNumber', 'kwargs': {'x': 4.0, 'y': 2.0}}
类型(作为字典,包含成员
'__kind__': <Kind.Type: 'type'>
)。>>> encode(ComplexNumber) {'__kind__': <Kind.Type: 'type'>, 'class': 'gluonts.core.serde._base.ComplexNumber'}
- 参数
v – 要编码的值。
- 返回
v
的编码,可以序列化为 Python 代码或 JSON 字符串。- 返回类型
Any