Effective Python 读书笔记: 第26条: 只在使用Min-in组件制作工具类时进行多重继承

# -*- encoding: utf-8 -*-

import json

'''
第26条: 只在使用Min-in组件制作工具类时进行多重继承

关键:
1 关于多重继承
建议:尽量避免多重继承
好处: 利用多重继承的封装性
实现: 多重继承编写mix-in类,只定义其他类可能需要提供的一套附加方法,
而不定义自己的实例属性,不要求使用者调用自己的__init__构造器

2 mix-in
优点: 子类可以继承父类的通用功能,并可以覆写它们

3 总结
1) 能用mix-in组件实现效果,就不要用多重继承
2) 将各个功能实现为可插拔的mix-in组件,让类继承自己需要的组件,定制需要的功能
3) 把多个mix-in组合出复杂的行为

参考:
Effectiv Python 编写高质量Python代码的59个有效方法

'''

class ToDictMixin(object):
    def to_dict(self):
        return self._traverse_dict(self.__dict__)

    def _traverse_dict(self, instanceDict):
        result = {}
        for key, value in instanceDict.items():
            result[key] = self._traverse(key, value)
        return result

    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


class BinaryTreeWithParent(BinaryTree):
    def __init__(
            self, value, left=None, right=None, parent=None):
        super(BinaryTreeWithParent, self).__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(BinaryTreeWithParent, self)._traverse(key, value)

class JsonMixin(object):
    @classmethod
    def fromJson(cls, data):
        kwargs = json.loads(data)
        return cls(**kwargs)

    def toJson(self):
        return json.dumps(self.to_dict())


class DataTools(ToDictMixin, JsonMixin):
    def __init__(self, switch=None, machines=None):
        self.switch = Switch(**switch)
        self.machines = [
            Machine(**kwargs) for kwargs in machines
        ]


class Switch(ToDictMixin, JsonMixin):
    def func(self):
        pass

class Machine(ToDictMixin, JsonMixin):
    def func(self):
        pass


def getBinaryTree():
    tree = BinaryTree(
        10,
        left=BinaryTree(7, right=BinaryTree(9)),
        right=BinaryTree(13, left=BinaryTree(11))
    )
    result = tree.to_dict()
    print result

    root = BinaryTreeWithParent(10)
    root.left = BinaryTreeWithParent(7, parent=root)
    root.left.right = BinaryTreeWithParent(9, parent=root.left)
    result = root.to_dict()
    print result


def serializion():
    serialized = """{
        "switch": {"port": 5, "speed": 1e9},
        "machines": [
            {"cores": 8, "ram": 32e9, "disk": 5e12},
            {"cores": 3, "ram": 32e9, "disk": 5e12},
            {"cores": 1, "ram": 32e9, "disk": 5e12},
        ]
    }
    """
    desiralized = DataTools.fromJson(serialized)
    print desiralized
    result = desiralized.toJson()
    assert json.loads(serialized) == json.loads(result)


def process():
    getBinaryTree()
    # serializion()

if __name__ == "__main__":
    process() 

猜你喜欢

转载自blog.csdn.net/qingyuanluofeng/article/details/88914815