0001 """A more or less complete user-defined wrapper around dictionary objects.""" 0002 0003 class UserDict: 0004 def __init__(self, dict=None, **kwargs): 0005 self.data = {} 0006 if dict is not None: 0007 self.update(dict) 0008 if len(kwargs): 0009 self.update(kwargs) 0010 def __repr__(self): return repr(self.data) 0011 def __cmp__(self, dict): 0012 if isinstance(dict, UserDict): 0013 return cmp(self.data, dict.data) 0014 else: 0015 return cmp(self.data, dict) 0016 def __len__(self): return len(self.data) 0017 def __getitem__(self, key): return self.data[key] 0018 def __setitem__(self, key, item): self.data[key] = item 0019 def __delitem__(self, key): del self.data[key] 0020 def clear(self): self.data.clear() 0021 def copy(self): 0022 if self.__class__ is UserDict: 0023 return UserDict(self.data.copy()) 0024 import copy 0025 data = self.data 0026 try: 0027 self.data = {} 0028 c = copy.copy(self) 0029 finally: 0030 self.data = data 0031 c.update(self) 0032 return c 0033 def keys(self): return self.data.keys() 0034 def items(self): return self.data.items() 0035 def iteritems(self): return self.data.iteritems() 0036 def iterkeys(self): return self.data.iterkeys() 0037 def itervalues(self): return self.data.itervalues() 0038 def values(self): return self.data.values() 0039 def has_key(self, key): return self.data.has_key(key) 0040 def update(self, dict=None, **kwargs): 0041 if dict is None: 0042 pass 0043 elif isinstance(dict, UserDict): 0044 self.data.update(dict.data) 0045 elif isinstance(dict, type({})) or not hasattr(dict, 'items'): 0046 self.data.update(dict) 0047 else: 0048 for k, v in dict.items(): 0049 self[k] = v 0050 if len(kwargs): 0051 self.data.update(kwargs) 0052 def get(self, key, failobj=None): 0053 if not self.has_key(key): 0054 return failobj 0055 return self[key] 0056 def setdefault(self, key, failobj=None): 0057 if not self.has_key(key): 0058 self[key] = failobj 0059 return self[key] 0060 def pop(self, key, *args): 0061 return self.data.pop(key, *args) 0062 def popitem(self): 0063 return self.data.popitem() 0064 def __contains__(self, key): 0065 return key in self.data 0066 def fromkeys(cls, iterable, value=None): 0067 d = cls() 0068 for key in iterable: 0069 d[key] = value 0070 return d 0071 fromkeys = classmethod(fromkeys) 0072 0073 class IterableUserDict(UserDict): 0074 def __iter__(self): 0075 return iter(self.data) 0076 0077 class DictMixin: 0078 # Mixin defining all dictionary methods for classes that already have 0079 # a minimum dictionary interface including getitem, setitem, delitem, 0080 # and keys. Without knowledge of the subclass constructor, the mixin 0081 # does not define __init__() or copy(). In addition to the four base 0082 # methods, progressively more efficiency comes with defining 0083 # __contains__(), __iter__(), and iteritems(). 0084 0085 # second level definitions support higher levels 0086 def __iter__(self): 0087 for k in self.keys(): 0088 yield k 0089 def has_key(self, key): 0090 try: 0091 value = self[key] 0092 except KeyError: 0093 return False 0094 return True 0095 def __contains__(self, key): 0096 return self.has_key(key) 0097 0098 # third level takes advantage of second level definitions 0099 def iteritems(self): 0100 for k in self: 0101 yield (k, self[k]) 0102 def iterkeys(self): 0103 return self.__iter__() 0104 0105 # fourth level uses definitions from lower levels 0106 def itervalues(self): 0107 for _, v in self.iteritems(): 0108 yield v 0109 def values(self): 0110 return [v for _, v in self.iteritems()] 0111 def items(self): 0112 return list(self.iteritems()) 0113 def clear(self): 0114 for key in self.keys(): 0115 del self[key] 0116 def setdefault(self, key, default=None): 0117 try: 0118 return self[key] 0119 except KeyError: 0120 self[key] = default 0121 return default 0122 def pop(self, key, *args): 0123 if len(args) > 1: 0124 raise TypeError, "pop expected at most 2 arguments, got "\ 0125 + repr(1 + len(args)) 0126 try: 0127 value = self[key] 0128 except KeyError: 0129 if args: 0130 return args[0] 0131 raise 0132 del self[key] 0133 return value 0134 def popitem(self): 0135 try: 0136 k, v = self.iteritems().next() 0137 except StopIteration: 0138 raise KeyError, 'container is empty' 0139 del self[k] 0140 return (k, v) 0141 def update(self, other=None, **kwargs): 0142 # Make progressively weaker assumptions about "other" 0143 if other is None: 0144 pass 0145 elif hasattr(other, 'iteritems'): # iteritems saves memory and lookups 0146 for k, v in other.iteritems(): 0147 self[k] = v 0148 elif hasattr(other, 'keys'): 0149 for k in other.keys(): 0150 self[k] = other[k] 0151 else: 0152 for k, v in other: 0153 self[k] = v 0154 if kwargs: 0155 self.update(kwargs) 0156 def get(self, key, default=None): 0157 try: 0158 return self[key] 0159 except KeyError: 0160 return default 0161 def __repr__(self): 0162 return repr(dict(self.iteritems())) 0163 def __cmp__(self, other): 0164 if other is None: 0165 return 1 0166 if isinstance(other, DictMixin): 0167 other = dict(other.iteritems()) 0168 return cmp(dict(self.iteritems()), other) 0169 def __len__(self): 0170 return len(self.keys()) 0171
Generated by PyXR 0.9.4