> 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)". _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion