- collections.abc 入门
# 定义个二叉树 ,希望可以
# 输出列表,是二叉树的前序遍历
# 可以进行索引取值,可以获取长度
https://zhuanlan.zhihu.com/p/142663602
### 普通方法
class BinaryNode(object):
    def __init__(self, value, left=None, right=None):
        self.value = value
        self.left = left
        self.right = right
class IndexableNode(BinaryNode):
    def __init__(self, value, left=None, right=None):
        super().__init__(value, left=left, right=right)
    def __repr__(self):
        return '{}'.format(self.pre_order_by_stack())
    def pre_order_by_stack(self, index=None):
        if self is None:
            return []
        stack, res = [self], []
        while stack:
            node = stack.pop()
            res.append(node.value)
            if index is not None:
                if index < 0:
                    raise ValueError('index must >= 0')
                if len(res) == index + 1:
                    break
            if node.right is not None:
                stack.append(node.right)
            if node.left is not None:
                stack.append(node.left)
        if index is not None and len(res) != index + 1:
            raise ValueError('index {} out of range'.format(index))
        return res
    def __getitem__(self, index=None):           # [self] 使用
        return self.pre_order_by_stack(index)[0]
    def __len__(self):
        return len(self.pre_order_by_stack())
tree = IndexableNode(
    10,
    left=IndexableNode(
        5,
        left=IndexableNode(2),
        right=IndexableNode(
            6,
            right=IndexableNode(7)
        )
    ),
    right=IndexableNode(
        15,
        left=IndexableNode(11)
    )
)
if __name__ == '__main__':
    print(tree.pre_order_by_stack())
    assert len(tree) == 7
    assert tree[0] == 10
    try:
        tree[7]
    except Exception as e:
        print(e)
    assert 10 in tree
    print(tree)
### 使用collections.abc方法
from collections.abc import Sequence
class BinaryNode(object):
    def __init__(self, value, left=None, right=None):
        self.value = value
        self.left = left
        self.right = right
class IndexableNode(BinaryNode, Sequence):
    def __init__(self, value, left=None, right=None):
        super().__init__(value, left=left, right=right)
    def __repr__(self):
        return '{}'.format(self.pre_order_by_stack())
    def pre_order_by_stack(self, index=None):
        if self is None:
            return []
        stack, res = [self], []
        while stack:
            node = stack.pop()
            res.append(node.value)
            if index is not None:
                if index < 0:
                    raise ValueError('index must >= 0')
                if len(res) == index + 1:
                    return node.value
            if node.right is not None:
                stack.append(node.right)
            if node.left is not None:
                stack.append(node.left)
        if index is not None and len(res) != index + 1:
            raise ValueError('index {} out of range'.format(index))
        return res
    def __getitem__(self, index):
        return self.pre_order_by_stack(index)
    def __len__(self):
        return len(self.pre_order_by_stack())
tree = IndexableNode(
    10,
    left=IndexableNode(
        5,
        left=IndexableNode(2),
        right=IndexableNode(
            6,
            right=IndexableNode(7)
        )
    ),
    right=IndexableNode(
        15,
        left=IndexableNode(11)
    )
)
if __name__ == '__main__':
    print(tree.pre_order_by_stack())
    assert len(tree) == 7
    assert tree[0] == 10
    try:
        tree[7]
    except Exception as e:
        print(e)
    assert 10 in tree, '0 not in tree'
    assert tree.index(15) == 5, 'the index of 15 is 5'
- NormalizedDict的作用
    other = {'d':'dd','b':'bb','C':'Cc'}
    other = NormalizedDict(other)
    print(other._data) # 数据,key变小写
    print(other._keys) # 小写key:原生的key
    print(other)  #排序原生数据
    print(normalize('D') in other)  # True
    '''
    {'d': 'dd', 'b': 'bb', 'c': 'Cc'}
    {'d': 'd', 'b': 'b', 'c': 'C'}
    {'b': 'bb', 'C': 'Cc', 'd': 'dd'}
    True
    '''
- ConnectionCache 的使用方法
from robot.utils import ConnectionCache
class SSHConnectionCache(ConnectionCache):
    def __init__(self):
        ConnectionCache.__init__(self, no_current_msg='No open connection.')
    @property
    def connections(self):
        return self._connections
    @property
    def aliases(self):
        return self._aliases
    def close_current(self):
        connection = self.current
        connection.close()
        if connection.config.alias is not None:
            self.aliases.pop(connection.config.alias)
        idx = connection.config.index - 1
        self.connections[idx] = self.current = self._no_current
    def close_all(self):
        open_connections = (conn for conn in self._connections if conn)
        for connection in open_connections:
            connection.close()
        self.empty_cache()
        return self.current
    def get_connection(self, alias_or_index=None):
        connection = super(SSHConnectionCache, self).get_connection(alias_or_index)
        if not connection:
            raise RuntimeError("Non-existing index or alias '%s'." % alias_or_index)
        return connection