title: How to understand lazy function in Django utils functional module
body: <p>I am learning from Django source code.
  When I read about functional module in Django,
  I don't know how to understand it.
  What the function is for and how to explain the implement of it.</p>
  
  <p>This is my first to use stackoverflow.
  If some rules in here I didn't notice, please remind me.Thanks.</p>
  
  <p>the code:</p>
  
  <pre><code>class Promise(object):
      """
      This is just a base class for the proxy class created in
      the closure of the lazy function. It can be used to recognize
      promises in code.
      """
      pass
  
  
  def lazy(func, *resultclasses):
      """
      Turns any callable into a lazy evaluated callable. You need to give result
      classes or types -- at least one is needed so that the automatic forcing of
      the lazy evaluation code is triggered. Results are not memoized; the
      function is evaluated on every access.
      """
  
      @total_ordering
      class __proxy__(Promise):
          """
          Encapsulate a function call and act as a proxy for methods that are
          called on the result of that function. The function is not evaluated
          until one of the methods on the result is called.
          """
          __dispatch = None
  
          def __init__(self, args, kw):
              self.__args = args
              self.__kw = kw
              if self.__dispatch is None:
                  self.__prepare_class__()
  
          def __reduce__(self):
              return (
                  _lazy_proxy_unpickle,
                  (func, self.__args, self.__kw) + resultclasses
              )
  
          @classmethod
          def __prepare_class__(cls):
              cls.__dispatch = {}
              for resultclass in resultclasses:
                  cls.__dispatch[resultclass] = {}
                  for type_ in reversed(resultclass.mro()):
                      for (k, v) in type_.__dict__.items():
                          # All __promise__ return the same wrapper method, but
                          # they also do setup, inserting the method into the
                          # dispatch dict.
                          meth = cls.__promise__(resultclass, k, v)
                          if hasattr(cls, k):
                              continue
                          setattr(cls, k, meth)
              cls._delegate_bytes = bytes in resultclasses
              cls._delegate_text = six.text_type in resultclasses
              assert not (cls._delegate_bytes and cls._delegate_text), "Cannot call lazy() with both bytes and text return types."
              if cls._delegate_text:
                  if six.PY3:
                      cls.__str__ = cls.__text_cast
                  else:
                      cls.__unicode__ = cls.__text_cast
              elif cls._delegate_bytes:
                  if six.PY3:
                      cls.__bytes__ = cls.__bytes_cast
                  else:
                      cls.__str__ = cls.__bytes_cast
  
          @classmethod
          def __promise__(cls, klass, funcname, method):
              # Builds a wrapper around some magic method and registers that
              # magic method for the given type and method name.
              def __wrapper__(self, *args, **kw):
                  # Automatically triggers the evaluation of a lazy value and
                  # applies the given magic method of the result type.
                  res = func(*self.__args, **self.__kw)
                  for t in type(res).mro():
                      if t in self.__dispatch:
                          return self.__dispatch[t][funcname](res, *args, **kw)
                  raise TypeError("Lazy object returned unexpected type.")
  
              if klass not in cls.__dispatch:
                  cls.__dispatch[klass] = {}
              cls.__dispatch[klass][funcname] = method
              return __wrapper__
  
          def __text_cast(self):
              return func(*self.__args, **self.__kw)
  
          def __bytes_cast(self):
              return bytes(func(*self.__args, **self.__kw))
  
          def __cast(self):
              if self._delegate_bytes:
                  return self.__bytes_cast()
              elif self._delegate_text:
                  return self.__text_cast()
              else:
                  return func(*self.__args, **self.__kw)
  
          def __ne__(self, other):
              if isinstance(other, Promise):
                  other = other.__cast()
              return self.__cast() != other
  
          def __eq__(self, other):
              if isinstance(other, Promise):
                  other = other.__cast()
              return self.__cast() == other
  
          def __lt__(self, other):
              if isinstance(other, Promise):
                  other = other.__cast()
              return self.__cast() &lt; other
  
          def __hash__(self):
              return hash(self.__cast())
  
          def __mod__(self, rhs):
              if self._delegate_bytes and six.PY2:
                  return bytes(self) % rhs
              elif self._delegate_text:
                  return six.text_type(self) % rhs
              return self.__cast() % rhs
  
          def __deepcopy__(self, memo):
              # Instances of this class are effectively immutable. It's just a
              # collection of functions. So we don't need to do anything
              # complicated for copying.
              memo[id(self)] = self
              return self
  
      @wraps(func)
      def __wrapper__(*args, **kw):
          # Creates the proxy object, instead of the actual value.
          return __proxy__(args, kw)
  
      return __wrapper__
  </code></pre>