Mix-in 类
- 一种小型的类,它只定义其它类可能需要提供的一套附加方法,而不定义自己的类实例属性。此外,它也不要求使用者调用自己的
__init__
构造器。(避免多继承问题)
class ToDictMixin:
"""
把内存中的 python 对象转换为字典形式,以便将其序列化。
"""
def to_dict(self):
return self._traverse_dict(self.__dict__)
def _traverse_dict(self, instance_dict):
ouput = {}
for key, value in instance_dict.items():
ouput[key] = self._traverse(key, value)
return ouput
def _traverse(self, key, value):
if isinstance(value, ToDictMixin):
return value.to_dict()
elif isinstance(value, dict):
return self._traverse_dict(value)
elif isinstance(value, list):
return [self._traverse(key, i) for i in value]
elif hasattr(value, '__dict__'):
return self._traverse_dict(value.__dict__)
else:
return value
class BinaryTree(ToDictMixin):
def __init__(self, value, left=None, right=None):
self.value = value
self.left = left
self.right = right
self._dict = {'a': 1, 'b': 2}
self._list = [1, 2]
# tree = BinaryTree(10,
# left=BinaryTree(7, right=BinaryTree(9)),
# right=BinaryTree(13, left=BinaryTree(11))
# )
tree = BinaryTree(10, left=BinaryTree(7))
print(tree.to_dict())
输出
{
'value': 10,
'left': {
'value': 7,
'left': None,
'right': None,
'_dict': {
'a': 1,
'b': 2
},
'_list': [1, 2]
},
'right': None,
'_dict': {
'a': 1,
'b': 2
},
'_list': [1, 2]
}
Mix-in 优势:使用者可以随时安插这些通用的功能,并且在必要时候覆写他们
class BinaryTreeWithParent(BinaryTree):
def __init__(self, value, left=None, right=None, parent=None):
super().__init__(value, left=left, right=right)
self.parent = parent
def _traverse(self, key, value): # 覆写,避免重复解析父类,导致死循环
if isinstance(value, BinaryTreeWithParent) and key == "parent":
return value.value
else:
return super()._traverse(key, value)
root = BinaryTreeWithParent(10)
root.left = BinaryTreeWithParent(7, parent=root)
root.left.right = BinaryTreeWithParent(9, parent=root.left)
print(root.to_dict())
输出
{
'value': 10,
'left': {
'value': 7,
'left': None,
'right': {
'value': 9,
'left': None,
'right': None,
'_dict': {
'a': 1,
'b': 2
},
'_list': [1, 2],
'parent': 7
},
'_dict': {
'a': 1,
'b': 2
},
'_list': [1, 2],
'parent': 10
},
'right': None,
'_dict': {
'a': 1,
'b': 2
},
'_list': [1, 2],
'parent': None
}