|
1 | | -import operator |
2 | | - |
3 | 1 | class MultiMapping: |
4 | 2 | def __init__(self, *stores): |
5 | 3 | self.stores = list(stores) |
| 4 | + self.stores.reverse() |
| 5 | + |
6 | 6 | def __getitem__(self, key): |
7 | 7 | for store in self.stores: |
8 | 8 | if store.has_key(key): |
9 | 9 | return store[key] |
10 | 10 | raise KeyError, key |
| 11 | + |
| 12 | + def __setitem__(self, key, val): |
| 13 | + self.stores[0][key] = val |
| 14 | + |
11 | 15 | _marker = [] |
| 16 | + |
12 | 17 | def get(self, key, default=_marker): |
13 | 18 | for store in self.stores: |
14 | 19 | if store.has_key(key): |
15 | 20 | return store[key] |
16 | 21 | if default is self._marker: |
17 | 22 | raise KeyError, key |
18 | 23 | return default |
| 24 | + |
19 | 25 | def __len__(self): |
20 | | - return reduce(operator.add, [len(x) for x in stores], 0) |
| 26 | + return len(self.items()) |
| 27 | + |
| 28 | + def has_key(self, key): |
| 29 | + for store in self.stores: |
| 30 | + if store.has_key(key): |
| 31 | + return 1 |
| 32 | + return 0 |
| 33 | + |
21 | 34 | def push(self, store): |
22 | | - self.stores.append(store) |
| 35 | + self.stores = [store] + self.stores |
| 36 | + |
23 | 37 | def pop(self): |
24 | | - return self.stores.pop() |
| 38 | + if not len(self.stores): |
| 39 | + return None |
| 40 | + store, self.stores = self.stores[0], self.stores[1:] |
| 41 | + return store |
| 42 | + |
| 43 | + def keys(self): |
| 44 | + return [ _[0] for _ in self.items() ] |
| 45 | + |
| 46 | + def values(self): |
| 47 | + return [ _[1] for _ in self.items() ] |
| 48 | + |
| 49 | + def copy(self): |
| 50 | + copy = MultiMapping() |
| 51 | + copy.stores = [_.copy() for _ in self.stores] |
| 52 | + return copy |
| 53 | + |
| 54 | + def items(self): |
| 55 | + l = [] |
| 56 | + seen = {} |
| 57 | + for store in self.stores: |
| 58 | + for k, v in store.items(): |
| 59 | + if not seen.has_key(k): |
| 60 | + l.append((k, v)) |
| 61 | + seen[k] = 1 |
| 62 | + return l |
25 | 63 |
|
0 commit comments