ATLAS Offline Software
Loading...
Searching...
No Matches
StackedDict.py
Go to the documentation of this file.
1# Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
2
3#
4# @file D3PDMakerCoreComps/python/StackedDict.py
5# @author scott snyder <snyder@bnl.gov>
6# @date Nov, 2012
7# @brief Allow lookups in multiple dictionaries while writing to one.
8#
9
10
11import collections.abc
12
13
14class StackedDict (collections.abc.Mapping):
15 """Allow lookups in multiple dictionaries while writing to one.
16
17 A StackedDict references a list of other dictionaries.
18 Reads try each dictionary in sequence, succeeding with the first dictionary
19 that contains the target key. Modifications go to the last dictionary
20 in the list.
21
22 Notes: No attempt is made to deal with keys duplicated between dictionaries;
23 len() and __iter__ will process them all. __delitem__ is not implemented.
24
25 Examples:
26 >>> from pprint import pprint
27 >>> d1 = {'a':'b'}
28 >>> d2 = {'c':'d'}
29 >>> d3 = {'e':'f'}
30 >>> d = StackedDict (d1, d2, d3)
31 >>> d['a']
32 'b'
33 >>> d['c']
34 'd'
35 >>> d['e']
36 'f'
37 >>> len(d)
38 3
39 >>> [x for x in d]
40 ['a', 'c', 'e']
41 >>> 'c' in d
42 True
43 >>> 'c' in d
44 True
45 >>> 'd' in d
46 False
47 >>> d['c'] = 10
48 >>> d['c']
49 10
50 >>> d2
51 {'c': 10}
52 >>> d['x'] = 20
53 >>> d['x']
54 20
55 >>> pprint(d3)
56 {'e': 'f', 'x': 20}
57 >>> pprint(d.copy())
58 {'a': 'b', 'c': 10, 'e': 'f', 'x': 20}
59"""
60
61 def __init__ (self, *dicts):
62 self.dicts = dicts
63 return
64
65
66 def __getitem__ (self, k):
67 for d in self.dicts:
68 if k in d:
69 return d[k]
70 raise KeyError (k)
71
72
73 def __setitem__ (self, k, v):
74 for d in self.dicts[:-1]:
75 if k in d:
76 d[k] = v
77 return
78 self.dicts[-1][k] = v
79 return
80
81
82 def __len__ (self):
83 return sum([len(d) for d in self.dicts])
84
85
86 def __iter__ (self):
87 for d in self.dicts:
88 for x in d: yield x
89 return
90
91
92 def has_key (self, k):
93 """Some code still uses this.
94 >>> d1 = {'a':'b'}
95 >>> d = StackedDict (d1)
96 >>> d.has_key ('a')
97 True
98 >>> d.has_key ('z')
99 False
100 """
101 return k in self
102
103
104 def copy (self):
105 d = {}
106 for i in range(len(self.dicts)-1, -1, -1):
107 d.update(self.dicts[i])
108 return d
109