PageRenderTime 225ms CodeModel.GetById 120ms app.highlight 17ms RepoModel.GetById 84ms app.codeStats 0ms

/Lib/UserDict.py

http://unladen-swallow.googlecode.com/
Python | 179 lines | 160 code | 8 blank | 11 comment | 46 complexity | 98d829f316bf2086f6bb0021c5bfcadd MD5 | raw file
  1"""A more or less complete user-defined wrapper around dictionary objects."""
  2
  3class UserDict:
  4    def __init__(self, dict=None, **kwargs):
  5        self.data = {}
  6        if dict is not None:
  7            self.update(dict)
  8        if len(kwargs):
  9            self.update(kwargs)
 10    def __repr__(self): return repr(self.data)
 11    def __cmp__(self, dict):
 12        if isinstance(dict, UserDict):
 13            return cmp(self.data, dict.data)
 14        else:
 15            return cmp(self.data, dict)
 16    def __len__(self): return len(self.data)
 17    def __getitem__(self, key):
 18        if key in self.data:
 19            return self.data[key]
 20        if hasattr(self.__class__, "__missing__"):
 21            return self.__class__.__missing__(self, key)
 22        raise KeyError(key)
 23    def __setitem__(self, key, item): self.data[key] = item
 24    def __delitem__(self, key): del self.data[key]
 25    def clear(self): self.data.clear()
 26    def copy(self):
 27        if self.__class__ is UserDict:
 28            return UserDict(self.data.copy())
 29        import copy
 30        data = self.data
 31        try:
 32            self.data = {}
 33            c = copy.copy(self)
 34        finally:
 35            self.data = data
 36        c.update(self)
 37        return c
 38    def keys(self): return self.data.keys()
 39    def items(self): return self.data.items()
 40    def iteritems(self): return self.data.iteritems()
 41    def iterkeys(self): return self.data.iterkeys()
 42    def itervalues(self): return self.data.itervalues()
 43    def values(self): return self.data.values()
 44    def has_key(self, key): return key in self.data
 45    def update(self, dict=None, **kwargs):
 46        if dict is None:
 47            pass
 48        elif isinstance(dict, UserDict):
 49            self.data.update(dict.data)
 50        elif isinstance(dict, type({})) or not hasattr(dict, 'items'):
 51            self.data.update(dict)
 52        else:
 53            for k, v in dict.items():
 54                self[k] = v
 55        if len(kwargs):
 56            self.data.update(kwargs)
 57    def get(self, key, failobj=None):
 58        if key not in self:
 59            return failobj
 60        return self[key]
 61    def setdefault(self, key, failobj=None):
 62        if key not in self:
 63            self[key] = failobj
 64        return self[key]
 65    def pop(self, key, *args):
 66        return self.data.pop(key, *args)
 67    def popitem(self):
 68        return self.data.popitem()
 69    def __contains__(self, key):
 70        return key in self.data
 71    @classmethod
 72    def fromkeys(cls, iterable, value=None):
 73        d = cls()
 74        for key in iterable:
 75            d[key] = value
 76        return d
 77
 78class IterableUserDict(UserDict):
 79    def __iter__(self):
 80        return iter(self.data)
 81
 82import _abcoll
 83_abcoll.MutableMapping.register(IterableUserDict)
 84
 85
 86class DictMixin:
 87    # Mixin defining all dictionary methods for classes that already have
 88    # a minimum dictionary interface including getitem, setitem, delitem,
 89    # and keys. Without knowledge of the subclass constructor, the mixin
 90    # does not define __init__() or copy().  In addition to the four base
 91    # methods, progressively more efficiency comes with defining
 92    # __contains__(), __iter__(), and iteritems().
 93
 94    # second level definitions support higher levels
 95    def __iter__(self):
 96        for k in self.keys():
 97            yield k
 98    def has_key(self, key):
 99        try:
100            value = self[key]
101        except KeyError:
102            return False
103        return True
104    def __contains__(self, key):
105        return self.has_key(key)
106
107    # third level takes advantage of second level definitions
108    def iteritems(self):
109        for k in self:
110            yield (k, self[k])
111    def iterkeys(self):
112        return self.__iter__()
113
114    # fourth level uses definitions from lower levels
115    def itervalues(self):
116        for _, v in self.iteritems():
117            yield v
118    def values(self):
119        return [v for _, v in self.iteritems()]
120    def items(self):
121        return list(self.iteritems())
122    def clear(self):
123        for key in self.keys():
124            del self[key]
125    def setdefault(self, key, default=None):
126        try:
127            return self[key]
128        except KeyError:
129            self[key] = default
130        return default
131    def pop(self, key, *args):
132        if len(args) > 1:
133            raise TypeError, "pop expected at most 2 arguments, got "\
134                              + repr(1 + len(args))
135        try:
136            value = self[key]
137        except KeyError:
138            if args:
139                return args[0]
140            raise
141        del self[key]
142        return value
143    def popitem(self):
144        try:
145            k, v = self.iteritems().next()
146        except StopIteration:
147            raise KeyError, 'container is empty'
148        del self[k]
149        return (k, v)
150    def update(self, other=None, **kwargs):
151        # Make progressively weaker assumptions about "other"
152        if other is None:
153            pass
154        elif hasattr(other, 'iteritems'):  # iteritems saves memory and lookups
155            for k, v in other.iteritems():
156                self[k] = v
157        elif hasattr(other, 'keys'):
158            for k in other.keys():
159                self[k] = other[k]
160        else:
161            for k, v in other:
162                self[k] = v
163        if kwargs:
164            self.update(kwargs)
165    def get(self, key, default=None):
166        try:
167            return self[key]
168        except KeyError:
169            return default
170    def __repr__(self):
171        return repr(dict(self.iteritems()))
172    def __cmp__(self, other):
173        if other is None:
174            return 1
175        if isinstance(other, DictMixin):
176            other = dict(other.iteritems())
177        return cmp(dict(self.iteritems()), other)
178    def __len__(self):
179        return len(self.keys())