code: def cached_property(method):
      
      name = method.__name__
  
      def newmethod(self):
          try:
              val = self.__dict__[name]
          except KeyError:
              val = method(self)
              self.__dict__[name] = val
          return val
      newmethod.__name__ = method.__name__
      newmethod.__doc__ = method.__doc__
      return property(newmethod)
docs: :param method: a method without arguments except self
      :returns: a cached property