实用工具
API 包 路径: mcdreforged.api.utils
- mcdreforged.utils.serializer.serialize(obj: Any) None | int | float | str | bool | list | dict [源代码]
一个工具函数,用于把任何对象序列化成一个 json 样式的 python 对象。在这里,拥有着 json 风格意味着其返回值可以直接作为参数传递给如
json.dumps()
序列化规则:
re.Pattern
会被转换为一个str
,其值为re.Pattern.pattern
。注意:如果re.Pattern.pattern
返回了一个bytes
,它将会被转换成一个 utf8 编码的str
普通的对象会被转换成一个包含了其所有公开属性的
dict
。键为属性的名字,值为序列化后的属性值
在 v2.8.0 版本加入: 如果对象是一个
Serializable
,那么其属性的顺序将与注解中顺序的保持一致在 v2.12.0 版本加入: 增加对基础类型的自定义子类、正则表达式对象(
re.Pattern
)的支持- 参数:
obj – 被序列化的对象
- 返回:
序列化结果
- mcdreforged.utils.serializer.deserialize(data: Any, cls: Type[T], *, error_at_missing: bool = False, error_at_redundancy: bool = False, missing_callback: Callable[[Any, Type, str], Any] | None = None, redundancy_callback: Callable[[Any, Type, str, Any], Any] | None = None) T [源代码]
一个工具函数,用于把一个 json 样式的 python 对象反序列化成给定的类
如果目标类包含嵌套的元素 / 属性,那么它们需要拥有详细的类型注解。这些元素 / 属性会被递归地反序列化
支持的目标类:
标准容器:
list
,dict
。需要用类型注解表示容器中的元素typing.List
,list
:目标类应当形如List[int]
或list[int]
(python 3.9+)typing.Dict
,dict
:目标类应当形如Dict[str, bool]
或dict[str, bool]
(python 3.9+)
typing 模块中的类型
typing.Union
:遍历所有可能的候选类,返回第一个成功的反序列化结果typing.Optional
:实际上它会被自动转换为typing.Union
typing.Any
:输入数据会被直接作为结果返回typing.Literal
:输入数据需要存在于Literal
的参数列表中,然后输入数据会被作为结果返回
正则表达式对象(
re.Pattern
)。这时输入数据应该是一个str
普通类:这个类应当类型注解完善其所有属性,并且其构造函数应当可接受 0 个入参。类例子:
class MyClass: some_str: str a_list: List[int]
输入数据应该是一个 dict。dict 中的键和值对应着属性的名称以及序列化的属性值。dict 例子:
{'some_str': 'foo', 'a_list': [1, 2, 3]}
将使用
__setattr__
设置对象的属性,非公开属性将被忽略
- 参数:
data – 被反序列化的 json 样式的对象
cls – 目标类,同时也是返回值的类型
- 关键字参数:
error_at_missing – 一个用于标识在反序列化一个对象的过程中,若对象存在未被赋值的属性,是否应该抛出异常的 flag。默认值为 false
error_at_redundancy – 一个用于标识在反序列化一个对象的过程中,若出现未知的输入属性,是否应该抛出异常的 flag。默认值为 false
missing_callback – 在反序列化对象过程中,发现对象存在未被赋值的属性时,调用的回调函数。该回调函数接受 3 个参数:此函数的 data 和 cls 参数,以及对象缺失属性的名称
redundancy_callback – 在反序列化对象过程中,遇到未知的输入属性时,调用的回调函数。该回调函数接受 4 个参数:此函数的 data 和 cls 参数,以及字典 data 中那个多余键值对的键和值
- 抛出:
TypeError – 若输入数据与目标类不匹配,或者目标类不在支持范围
ValueError – 如果输入数据非法,这包括
Literal
匹配失败,以及那些 kwargs 里的抛异常 flag 起了效果
- 返回:
一个类型为
cls
的对象
在 v2.7.0 版本加入: 增加对
typing.Literal
的支持在 v2.12.0 版本加入: 增加对基础类型的自定义子类、正则表达式对象(
re.Pattern
)的支持
- class mcdreforged.utils.serializer.Serializable(**kwargs)[源代码]
一个用于便捷序列化/反序列化的抽象类
继承它,并在你的子类中使用类型注解声明属性,你所需要做的就这么多
例子:
>>> class MyData(Serializable): ... name: str ... values: List[int] >>> data = MyData.deserialize({'name': 'abc', 'values': [1, 2]}) >>> print(data.name, data.values) abc [1, 2] >>> data.serialize() {'name': 'abc', 'values': [1, 2]} >>> data = MyData(name='cde') >>> data.serialize() {'name': 'cde'}
类
Serializable
的嵌套也是支持的:class MyStorage(Serializable): id: str best: MyData data: Dict[str, MyData]
你也可以在声明类型注解时声明属性的默认值,这样在反序列化的过程中,如果值缺失,则默认值的
copy.copy()
将会被赋值>>> class MyArray(Serializable): ... array: List[int] = [0] >>> a = MyArray(array=[1]) >>> print(a.array) [1] >>> b, c = MyArray.deserialize({}), MyArray.deserialize({}) >>> print(b.array) [0] >>> b.array == c.array == MyArray.array True >>> b.array is not c.array is not MyArray.array True
枚举类会被序列化为它的枚举成员名称:
>>> class Gender(Enum): ... male = 'man' ... female = 'woman' >>> class Person(Serializable): ... name: str = 'zhang_san' ... gender: Gender = Gender.male >>> data = Person.get_default() >>> data.serialize() {'name': 'zhang_san', 'gender': 'male'} >>> data.gender = Gender.female >>> data.serialize() {'name': 'zhang_san', 'gender': 'female'} >>> Person.deserialize({'name': 'li_si', 'gender': 'female'}).gender == Gender.female True
- __init__(**kwargs)[源代码]
使用给定的属性值创建一个
Serializable
对象未指定的,在类型注解中含有默认值的属性,将被设为默认值的一个拷贝(
copy.copy()
)- 参数:
kwargs – 一个储存着用于设置属性的值的 dict。dict 的键为属性名,值为属性值
- classmethod get_field_annotations() Dict[str, Type] [源代码]
一个用来提取类的属性注解声明的辅助方法
只有公开属性会被提取。保护或私有的属性会被忽略
返回值会被缓存,以便于复用
- 返回:
一个储存了这个类声明的属性注解的 dict。其中键为属性名,值为对应属性的类型注解
在 v2.8.0 版本加入.
- serialize() dict [源代码]
借助函数
serialize()
,将自身序列化为一个 dict
- classmethod deserialize(data: dict, **kwargs) Self [源代码]
借助函数
deserialize()
,将一个 dict 反序列化为一个这个类的实例如果存在缺失的属性,若可能,自动从类定义中拷贝默认值。见
__init__()
以了解更多的信息
- copy(*, deep: bool = True) Self [源代码]
创建一份此对象的拷贝。只有在类的注解中声明了的属性会被拷贝
默认情况下,创建深拷贝
- 关键字参数:
deep – 是否应该创建深拷贝。True:深拷贝,False:浅拷贝
在 v2.8.0 版本加入.
在 v2.9.0 版本加入: 添加
deep
关键字参数
- validate_attribute(attr_name: str, attr_value: Any, **kwargs)[源代码]
一个将于反序列化期间,在设置属性值之前被调用的方法
你可以在这个方法中验证即将设置的属性值,并对期望之外的值抛出
ValueError
异常- 参数:
attr_name – 将被设置的属性的名字
attr_value – 将被设置的属性值
- 关键字参数:
kwargs – 占位符
- 抛出:
ValueError – 若验证失败
在 v2.8.0 版本加入.