Introduction to Python: Class 6

Page Contents


Polymorphism

Emulating Callable Types

      __call__(self, parameterlist)

      x.(...) == x.__call__(...)
    

Emulating Sequences

      class lazyconst:
	  """
	  Infinite lazy list of some constant: e.g. lazyconst(0) is an
	  infinite list of zeroes.
	  """
	  def __init__(self, const):
	      self.const = const
	  def __len__(self):
	      # prevents use with map, filter and reduce
	      raise TypeError, "infinite length"
	  def __getitem__(self, index):
	      return self.const
	  def __repr__(self):
	      return "[%s...]" % self.const
	  def __getslice__(self, i, j):
	      # won't work with negative slice indices because python will
	      # try to call self.__len__
	      return [self.const] * (j-i)
    

Emulating Mappings

      class defaultdict(UserDict.UserDict):
	  """
	  A dictionary that returns a default value for keys that aren't present
	  """
	  def __init__(self, default):
	      UserDict.UserDict.__init__(self)
	      self.default = default
	  def __getitem__(self, key):
	      return self.data.get(key, self.default)
	  def has_key(self, key):
	      return 1

      class defaultdict(UserDict.UserDict):
	  """
	  More sophisticated version of defaultdict: if sticky == 1, then
	  merely looking up a value actually stores the value; this is good
	  for mutable defaults, as it allows, e.g.:
	      d = defaultdict([], sticky=1)
	      d["whatever"].append(1)
	  """
	  def __init__(self, default, sticky = 0):
	      UserDict.UserDict.__init__(self)
	      self.default, self.sticky = default, sticky
	  def __getitem__(self, key):
	      if self.sticky:
		  if self.data.has_key(key):
		      return self.data[key]
		  else:
		      # question: why do we need to use copy?
		      # question: why do we use result?
		      self.data[key] = result = copy(self.default)
		      return result
	      else:
		  return self.data.get(key, self.default)
	  def has_key(self, key):
	      return 1

      class quotedict(UserDict.UserDict):
	  def __init__(self, dict, quote):
	      self.data = dict
	      self.quote = quote
	  def __getitem__(self, key):
	      return self.quote(self.data[key])
    

Emulating Numeric Types

      class register:
	  """
	  Mutable registers
	  """
	  def __init__(self):
	      self.n = 0
	  def __repr__(self):
	      return `self.n`
	  def __coerce__(self, other):
	      return (self.n, other)
	  def __int__(self):
	      return self.n
	  def __cmp__(self, other):
	      return cmp(self.n, int(other))
	  def __nonzero__(self):
	      return self.n
	  def inc(self, step=1):
	      self.n = self.n + step
	      return self.n
	  def dec(self, step=1):
	      self.n = self.n - step
	      return self.n
    

Example Code

Example Code.