code: def astype(self, out_dtype):
          
          out_dtype = np.dtype(out_dtype)
          if out_dtype == self.out_dtype:
              return self
  
          # Try to use caching for real and complex versions (exact dtype
          # mappings). This may fail for certain dtype, in which case we
          # just go to `_astype` directly.
          real_dtype = getattr(self, 'real_out_dtype', None)
          if real_dtype is None:
              return self._astype(out_dtype)
          else:
              if out_dtype == real_dtype:
                  if self.__real_space is None:
                      self.__real_space = self._astype(out_dtype)
                  return self.__real_space
              elif out_dtype == self.complex_out_dtype:
                  if self.__complex_space is None:
                      self.__complex_space = self._astype(out_dtype)
                  return self.__complex_space
              else:
                  return self._astype(out_dtype)
docs: Return a copy of this space with new ``out_dtype``.
  
          Parameters
          ----------
          out_dtype :
              Output data type of the returned space. Can be given in any
              way `numpy.dtype` understands, e.g. as string (``'complex64'``)
              or built-in type (``complex``). ``None`` is interpreted as
              ``'float64'``.
  
          Returns
          -------
          newspace : `FunctionSpace`
              The version of this space with given data type