def shape(self):
        """Total spaces per axis, computed recursively.

        The recursion ends at the fist level that does not have a shape.

        Examples
        --------
        >>> r2, r3 = odl.rn(2), odl.rn(3)
        >>> pspace = odl.ProductSpace(r2, r3)
        >>> pspace.shape
        (2,)
        >>> pspace2 = odl.ProductSpace(pspace, 3)
        >>> pspace2.shape
        (3, 2)

        If the space is a "pure" product space, shape recurses all the way
        into the components:

        >>> r2_2 = odl.ProductSpace(r2, 3)
        >>> r2_2.shape
        (3, 2)
        """
        if len(self) == 0:
            return ()
        elif self.is_power_space:
            try:
                sub_shape = self[0].shape
            except AttributeError:
                sub_shape = ()
        else:
            sub_shape = ()

        return (len(self),) + sub_shape
Total spaces per axis, computed recursively.

        The recursion ends at the fist level that does not have a shape.

        Examples
        --------
        >>> r2, r3 = odl.rn(2), odl.rn(3)
        >>> pspace = odl.ProductSpace(r2, r3)
        >>> pspace.shape
        (2,)
        >>> pspace2 = odl.ProductSpace(pspace, 3)
        >>> pspace2.shape
        (3, 2)

        If the space is a "pure" product space, shape recurses all the way
        into the components:

        >>> r2_2 = odl.ProductSpace(r2, 3)
        >>> r2_2.shape
        (3, 2)