summaryrefslogtreecommitdiff
path: root/Lib/UserDict.py
diff options
context:
space:
mode:
authorRaymond Hettinger <python@rcn.com>2002-11-18 04:34:10 +0000
committerRaymond Hettinger <python@rcn.com>2002-11-18 04:34:10 +0000
commit8ddc176e2e7ef11b2c46062b29563bc776f177b8 (patch)
tree9420f4a710a3ae47f72c846c0b6f5e0c1a9a29bd /Lib/UserDict.py
parent782d9408667f8df924d865088839633f53cf89bc (diff)
downloadcpython-git-8ddc176e2e7ef11b2c46062b29563bc776f177b8.tar.gz
Improve DictMixin.
Replaced docstring with comments. Prevents subclass contamination. Added the missing __cmp__() method and a test for __cmp__(). Used try/except style in preference to has_key() followed by a look-up. Used iteritem() where possible to save creating a long key list and to save redundant lookups. Expanded .update() to look for the most helpful methods first and gradually work down to a mininum expected interface. Expanded documentation to be more clear on how to use the class.
Diffstat (limited to 'Lib/UserDict.py')
-rw-r--r--Lib/UserDict.py61
1 files changed, 38 insertions, 23 deletions
diff --git a/Lib/UserDict.py b/Lib/UserDict.py
index b6b36b2066..96f049dd94 100644
--- a/Lib/UserDict.py
+++ b/Lib/UserDict.py
@@ -62,13 +62,17 @@ class IterableUserDict(UserDict):
return iter(self.data)
class DictMixin:
- '''Mixin defining all dictionary methods for classes that already have
- a minimum dictionary interface including getitem, setitem, delitem,
- and keys '''
+ # Mixin defining all dictionary methods for classes that already have
+ # a minimum dictionary interface including getitem, setitem, delitem,
+ # and keys. Without knowledge of the subclass constructor, the mixin
+ # does not define __init__() or copy(). In addition to the four base
+ # methods, progessively more efficiency comes with defining
+ # __contains__(), __iter__(), and iteritems().
- # first level provided by subclass: getitem, setitem, delitem, and keys
-
- # second level definitions which assume only getitem and keys
+ # second level definitions support higher levels
+ def __iter__(self):
+ for k in self.keys():
+ yield k
def has_key(self, key):
try:
value = self[key]
@@ -76,34 +80,30 @@ class DictMixin:
return False
return True
__contains__ = has_key
- def __iter__(self):
- for k in self.keys():
- yield k
- def __len__(self):
- return len(self.keys())
- # third level uses second level instead of first
+ # third level takes advantage of second level definitions
def iteritems(self):
for k in self:
yield (k, self[k])
iterkeys = __iter__
- # fourth level uses second and third levels instead of first
+ # fourth level uses definitions from lower levels
def itervalues(self):
for _, v in self.iteritems():
yield v
def values(self):
- return [self[key] for key in self.keys()]
+ return [v for _, v in self.iteritems()]
def items(self):
return list(self.iteritems())
def clear(self):
for key in self.keys():
del self[key]
def setdefault(self, key, default):
- if key not in self:
+ try:
+ return self[key]
+ except KeyError:
self[key] = default
- return default
- return self[key]
+ return default
def pop(self, key):
value = self[key]
del self[key]
@@ -112,15 +112,30 @@ class DictMixin:
try:
k, v = self.iteritems().next()
except StopIteration:
- raise KeyError, 'dictionary is empty'
+ raise KeyError, 'container is empty'
del self[k]
return (k, v)
def update(self, other):
- for key in other.keys():
- self[key] = other[key]
+ # Make progressively weaker assumptions about "other"
+ if hasattr(other, 'iteritems'): # iteritems saves memory and lookups
+ for k, v in other.iteritems():
+ self[k] = v
+ elif hasattr(other, '__iter__'): # iter saves memory
+ for k in other:
+ self[k] = other[k]
+ else:
+ for k in other.keys():
+ self[k] = other[k]
def get(self, key, default=None):
- if key in self:
+ try:
return self[key]
- return default
+ except KeyError:
+ return default
def __repr__(self):
- return repr(dict(self.items()))
+ return repr(dict(self.iteritems()))
+ def __cmp__(self, other):
+ if isinstance(other, DictMixin):
+ other = dict(other.iteritems())
+ return cmp(dict(self.iteritems()), other)
+ def __len__(self):
+ return len(self.keys())