使反序列化变得容易的库。
deserialize的Python项目详细描述
反序列化
使反序列化变得容易的库。要开始,只需运行pip install deserialize
过去的情况
如果不使用库,则要转换:
{
"a": 1,
"b": 2
}
进入一个专门的班级,你必须做这样的事情:
class MyThing:
def __init__(self, a, b):
self.a = a
self.b = b
@staticmethod
def from_json(json_data):
a_value = json_data.get("a")
b_value = json_data.get("b")
if a_value is None:
raise Exception("'a' was None")
elif b_value is None:
raise Exception("'b' was None")
elif type(a_value) != int:
raise Exception("'a' was not an int")
elif type(b_value) != int:
raise Exception("'b' was not an int")
return MyThing(a_value, b_value)
my_instance = MyThing.from_json(json_data)
现在情况如何
使用deserialize
您只需要这样做:
import deserialize
class MyThing:
a: int
b: int
my_instance = deserialize.deserialize(MyThing, json_data)
就这样。它将提取所有数据,并为您设置类型检查,甚至检查空值。
如果希望允许空值,也很容易:
from typing import Optional
class MyThing:
a: Optional[int]
b: Optional[int]
现在None
是它们的有效值。
类型可以嵌套得尽可能深。例如,这是完全有效的:
class Actor:
name: str
age: int
class Episode:
title: str
identifier: st
actors: List[Actor]
class Season:
episodes: List[Episode]
completed: bool
class TVShow:
seasons: List[Season]
creator: str
高级用法
自定义键
可能是您希望在对象中为属性命名与数据中不同的名称。这可能是由于可读性的原因,也可能是因为您必须这样做(例如,如果您的数据项名为__class__
)。这也可以处理。只需按如下方式使用key
注释:
@deserialize.key("identifier", "id")
class MyClass:
value: int
identifier: str
这将使用键id
将数据分配给字段identifier
。可以有多个注释来覆盖多个键。
忽略键
您可能希望对象中的某些属性不是从磁盘加载的,而是以其他方式创建的。为此,请使用ignore
装饰器。下面是一个示例:
@deserialize.ignore("identifier")
class MyClass:
value: int
identifier: str
反序列化时,库现在将忽略identifier
属性。
分析器
有时,您会希望对象中的某些内容采用数据不采用的格式。例如,如果获得数据:
{
"successful": True,
"timestamp": 1543770752
}
您可能希望将其表示为:
class Result:
successful: bool
timestamp: datetime.datetime
默认情况下,此反序列化将失败,因为数据中的值不是时间戳。若要更正此问题,请使用parser
修饰符告诉它要使用一个函数来解析数据。例如
@deserialize.parser("timestamp", datetime.datetime.fromtimestamp)
class Result:
successful: bool
timestamp: datetime.datetime
这将在处理keytimestamp
的数据时进行检测,并在将其分配给新类实例之前通过提供的解析器函数运行它。
在完成类型检查之前,将运行解析器。这意味着,如果您有类似Optional[datetime.datetime]
的内容,您应该确保解析器能够处理None
的值。您的解析器显然需要返回您在属性上声明的类型才能工作。