image is a multidimensional numpy array.  It is defined via a nested list of lists (the brackets and commas).
image.shape is a tuple, and so displays with ().
The other answers, and the supposed duplicate, focus on Python's distinction between lists and tuples.  But this needs a numpy focused answer.
A simple 3d array:
In [244]: x = np.array([[[1,2],[3,4]]])
In [245]: x
Out[245]: 
array([[[1, 2],
        [3, 4]]])
You can get the shape as a property, or via a function call
In [246]: x.shape
Out[246]: (1, 2, 2)
In [247]: np.shape(x)
Out[247]: (1, 2, 2)
But the shape does not have a shape property itself.  len(x.shape) would work, since it is a tuple.
In [248]: (x.shape).shape
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-248-b00338a7f4bf> in <module>()
----> 1 (x.shape).shape
AttributeError: 'tuple' object has no attribute 'shape'
np.shape(...shape) is confusing.  np.shape() will first turn its input into an array (if it isn't already) and return the shape of that:
In [249]: np.shape(x.shape)
Out[249]: (3,)
So I wouldn't normally take this shape of a shape.  However it does demonstrate a key point.  (3,) is a 1 element tuple.  The , is important.  The shape tuple for an 0d array is ().
The next part makes a 3 element array
In [250]: np.random.randn(3)
Out[250]: array([ 2.06265058,  0.87906775, -0.96525837])
In [251]: _.shape
Out[251]: (3,)
In [252]: print(__)
[ 2.06265058  0.87906775 -0.96525837]
Again, a (3,) shape tuple.  The str display of an array uses the brackets, but omits the commas.  That helps distinguish it from a regular list.
(There is also an array type that displays with (), a structured array. But that's a more advanced topic.)