[Python-checkins] python/dist/src/Lib UserDict.py,1.18,1.19

rhettinger@projects.sourceforge.net rhettinger@projects.sourceforge.net
Sun, 17 Nov 2002 20:34:12 -0800


Update of /cvsroot/python/python/dist/src/Lib
In directory sc8-pr-cvs1:/tmp/cvs-serv23016/Lib

Modified Files:
	UserDict.py 
Log Message:
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.



Index: UserDict.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/UserDict.py,v
retrieving revision 1.18
retrieving revision 1.19
diff -C2 -d -r1.18 -r1.19
*** UserDict.py	15 Nov 2002 06:46:13 -0000	1.18
--- UserDict.py	18 Nov 2002 04:34:10 -0000	1.19
***************
*** 63,73 ****
  
  class DictMixin:
!     '''Mixin defining all dictionary methods for classes that already have
!        a minimum dictionary interface including getitem, setitem, delitem,
!        and keys '''
! 
!     # first level provided by subclass: getitem, setitem, delitem, and keys
  
!     # second level definitions which assume only getitem and keys
      def has_key(self, key):
          try:
--- 63,77 ----
  
  class DictMixin:
!     # 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().
  
!     # second level definitions support higher levels
!     def __iter__(self):
!         for k in self.keys():
!             yield k
      def has_key(self, key):
          try:
***************
*** 77,87 ****
          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
      def iteritems(self):
          for k in self:
--- 81,86 ----
          return True
      __contains__ = has_key
  
!     # third level takes advantage of second level definitions
      def iteritems(self):
          for k in self:
***************
*** 89,98 ****
      iterkeys = __iter__
  
!     # fourth level uses second and third levels instead of first
      def itervalues(self):
          for _, v in self.iteritems():
              yield v
      def values(self):
!         return [self[key] for key in self.keys()]
      def items(self):
          return list(self.iteritems())
--- 88,97 ----
      iterkeys = __iter__
  
!     # fourth level uses definitions from lower levels
      def itervalues(self):
          for _, v in self.iteritems():
              yield v
      def values(self):
!         return [v for _, v in self.iteritems()]
      def items(self):
          return list(self.iteritems())
***************
*** 101,108 ****
              del self[key]
      def setdefault(self, key, default):
!         if key not in self:
              self[key] = default
!             return default
!         return self[key]
      def pop(self, key):
          value = self[key]
--- 100,108 ----
              del self[key]
      def setdefault(self, key, default):
!         try:
!             return self[key]
!         except KeyError:
              self[key] = default
!         return default
      def pop(self, key):
          value = self[key]
***************
*** 113,126 ****
              k, v = self.iteritems().next()
          except StopIteration:
!             raise KeyError, 'dictionary is empty'
          del self[k]
          return (k, v)
      def update(self, other):
!         for key in other.keys():
!             self[key] = other[key]
      def get(self, key, default=None):
!         if key in self:
              return self[key]
!         return default
      def __repr__(self):
!         return repr(dict(self.items()))
--- 113,141 ----
              k, v = self.iteritems().next()
          except StopIteration:
!             raise KeyError, 'container is empty'
          del self[k]
          return (k, v)
      def update(self, other):
!         # 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):
!         try:
              return self[key]
!         except KeyError:
!             return default
      def __repr__(self):
!         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())