Python 的 dataclass
是数据封装的好工具, 但它有个缺陷, 即无法支持可选字段.
例如给前端树形选择器提供的数据结构如下图所示
@dataclass
class TreeSelectOptionItem:
id: Union[str, int]
label: str
children: Optional[List['TreeSelectOptionItem']] = None
其中 children
是递归自身结构的字段, 但叶子结点可以没有该字段. 而 dataclass
则无法表示这样的数据结构, 因为上面声明的结构里, children
字段是必须存在, 只能用 None
来示意.
问题是, 有的场景下 None
和 没有该字段, 这两个情况并不等价. 例如树形选择器 Vue-Treeselect 中, children=null
表示该节点需要懒加载子节点数据. 这样, 后端的数据必须做一定的处理,才能传给前端.
如何能够优雅的解决这个问题呢? 这里给出一个解决方案:
一般, 在传给前端之前, 我们会用 asdict
方法去序列化 dataclass
, 所以可以考虑拦截这个方法. 这种思路的一个实现方式如下:
from dataclasses import dataclass, asdict
@dataclass
class TreeSelectOptionItem:
id: Union[str, int]
label: str
children: Optional[List['TreeSelectOptionItem']] = None
def as_dict(self):
# 先序列化
data = asdict(self)
# 过滤掉是None的字段
return {key: value for key, value in data.items() if value is not None}
网友评论