Here's a case where the copy=False works, returning the original array:
In [238]: x
Out[238]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [239]: y = x.astype(int,copy=False)
In [240]: id(x)
Out[240]: 2884971680
In [241]: id(y)
Out[241]: 2884971680 # same id
In [242]: z = x.astype(int)
In [243]: id(z)
Out[243]: 2812517656 # different id
In a sense this is a trivial case; but I wouldn't be surprised if every other case is just as trivial
In [244]: w = x.astype(int,order='F',copy=False)
In [245]: id(w)
Out[245]: 2884971680 # 1d array is both order C and F
In other words it returns the original array if required dtype and order don't require any changes. That is if the original already meets the specs.
This isn't the same as a view. A view is a new array (new id) but shared data buffer. Rather it is more like the simpler Python assignment, y = x.
I may change my mind if someone can some up with a copy=False case that involves a change in dtype.
The same call, but with a different array will create a copy
In [249]: x1=np.arange(10.) # float
In [250]: y1=x1.astype(int, copy=False)
In [251]: id(x1)
Out[251]: 2812517696
In [253]: id(y1)
Out[253]: 2812420768 # different id
In [254]: y1=x1.astype(float, copy=False)
In [255]: id(y1)
Out[255]: 2812517696
So you could use copy=False if you want, say a int dtype array, but without any loss in efficiency if the array is already int.
Efficient way to cast scalars to numpy arrays
np.array with copy=False behaves in much the same way - returning the same array (id) if no transformation is required.