[Numpy-discussion] numpy.complex
OC
oc-spam66 at laposte.net
Mon Jul 23 15:29:25 EDT 2012
> It's unPythonic just in the sense that it is unlike every other type
> constructor in Python. int(x) returns an int, list(x) returns a list,
> but np.complex64(x) sometimes returns a np.complex64, and sometimes it
> returns a np.ndarray, depending on what 'x' is.
This "object factory" design pattern adds useful and natural functionality.
> I can see an argument for deprecating this behaviour altogether and
> referring people to the np.asarray(x, dtype=complex) form; that would
> be cleaner and reduce confusion. Don't know if it's worth it, but
> that's the only cleanup that I can see even being considered for these
> constructors.
From my experience in teaching, I can tell that even beginners have no
problem with the fact that "complex128(1)" returns a scalar and that
"complex128(r_[1])" returns an array. It seems to be pretty natural.
Also, from the duck-typing point of view, both returned values are
complex, i.e. provide 'real' and 'imag' attributes and 'conjugate()' method.
On the contrary a real confusion is with "numpy.complex" acting
differently than the other "numpy.complex*".
> People do write "from numpy import *"
Yeah, that's what I do very often in interactive "ipython" sessions.
Other than this, people are warned often enough that this shouldn't be
used in real programs.
> and it would be very bad if that overwrote basic builtins like
> int/float/bool
True, but is it so bad? All the following is true when 'x' is a scalar:
complex(x) == numpy.complex_(x)
bool(x) == numpy.bool_(x)
float(x) == numpy.float_(x)
int(x) == numpy.int_(x)
isinstance(numpy.complex_(x), complex)
isinstance(numpy.int_(x), int)
isinstance(numpy.float_(x), float)
However, it's indeed a problem that "numpy.complex_(1,1)" is not
defined, contrary to "__builtin__.complex(1,1)" (but this looks easy to
implement).
> it's very difficult to deprecate exports, so I guess this will probably
> never happen.
With the move to Python 3, people are used to movement :-)
I will just summarize my opinion and understanding, in case someone is
interested:
* I find it ugly that:
- "numpy.real(A)" and "numpy.complex(A)" do not behave the same.
- "numpy.complex(A)" and "numpy.complex128(A)" do not behave the same.
* A solution could be to let "numpy.complex" be equal to
"numpy.complex_" (and the same for "int", "float", "bool").
- This would overwrite builtins in case of "from numpy import *".
- This may not be that harmful, except for the fact that
"numpy.complex_(1,1)" is not implemented, contrary to
"__builtin__.complex(1,1)".
More information about the NumPy-Discussion
mailing list