Last active
August 29, 2015 14:03
-
-
Save huyx/984c3340f332366d8a29 to your computer and use it in GitHub Desktop.
Merge dict or dict like object,, include OrderedDict。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
u'''合并字典,可用于配置信息合并 | |
合并的原则是后来的数据优先 | |
''' | |
def mergeable(target, source): | |
''' | |
>>> from collections import OrderedDict | |
>>> mergeable({}, {}) | |
True | |
>>> mergeable(OrderedDict(), {}) | |
True | |
>>> mergeable({}, OrderedDict()) | |
True | |
>>> mergeable('target', {}) | |
False | |
>>> mergeable([], {}) | |
False | |
>>> mergeable({}, 'source') | |
False | |
>>> mergeable({}, []) | |
False | |
''' | |
if isinstance(target, (basestring, tuple, list)): | |
return False | |
if isinstance(source, (basestring, tuple, list)): | |
return False | |
if isinstance(target, dict) and isinstance(source, dict): | |
return True | |
return all(( | |
hasattr(target, 'keys'), | |
hasattr(target, '__getitem__'), | |
hasattr(target, '__setitem__'), | |
hasattr(source, 'keys'), | |
hasattr(target, '__getitem__'), | |
)) | |
def merge_dict(target, source): | |
''' | |
>>> from collections import OrderedDict | |
>>> merge_dict(OrderedDict(), OrderedDict([('a', 1)])) | |
OrderedDict([('a', 1)]) | |
>>> merge_dict(OrderedDict([('a', 1)]), OrderedDict([('a', 2)])) | |
OrderedDict([('a', 2)]) | |
>>> merge_dict(OrderedDict([('a', 1)]), OrderedDict([('b', 2)])) | |
OrderedDict([('a', 1), ('b', 2)]) | |
''' | |
assert mergeable(target, source) | |
targetKeys = target.keys() | |
sourceKeys = source.keys() | |
for key in sourceKeys: | |
source_value = source[key] | |
if key in targetKeys: | |
target_value = target[key] | |
if mergeable(target_value, source_value): | |
merge_dict(target_value, source_value) | |
else: | |
target[key] = source_value | |
else: | |
target[key] = source_value | |
return target | |
if __name__ == '__main__': | |
import doctest | |
doctest.testmod() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment