[Python-Dev] basenumber redux

"Martin v. Löwis" martin at v.loewis.de
Tue Jan 17 07:41:13 CET 2006


Alex Martelli wrote:
>> As I suggested in a different message: Why are you doing that
>> in the first place?
> 
> 
> Because isinstance is faster and handier than testing with try/except 
> around (say) "x+0".

Nit: I think you should not test. Instead, you should starting you mean
to do if the test passes, and then expect TypeErrors from doing so.

> As to why I want to distinguish numbers from non-numbers, let me  quote
> from a message I sent in 2003 (one of the few you'll find by  searching
> for [basestring site:python.org] as I have repeatedly  recommended, but
> apparently there's no way to avoid just massively  copying and pasting...):

As I said in that other message, I found this one, and still don't
understand what the use case is, because the example you give still
reads hypothetical (I'm sure there is an actual example behind it, but
you don't say what that is).

> """
> def __mul__(self, other):
>     if isinstance(other, self.KnownNumberTypes):
>         return self.__class__([ x*other for x in self.items ])
>     else:
>         # etc etc, various other multiplication cases

So what *are* the "various other multiplication cases"?

You just shouldn't be doing that: multiplication shouldn't mean
"item multiplication" sometimes, and various other things if it
can't mean item multiplication.

> in  Python/bltinmodule.c , function builtin_sum uses C-coded  typechecking
> to single out strings as an error case:
> 
>         /* reject string values for 'start' parameter */
>         if (PyObject_TypeCheck(result, &PyBaseString_Type)) {
>             PyErr_SetString(PyExc_TypeError,
>                 "sum() can't sum strings [use ''.join(seq) instea

This is indeed confusing: why is it again that sum refuses to sum
up strings?

> [etc].  Now, what builtin_sum really "wants" to do is to accept numbers,
> only -- it's _documented_ as being meant for "numbers": it uses +, NOT
> +=, so its performance on sequences, matrix and array-ish things, etc,
> is not going to be good.  But -- it can't easily _test_ whether  something
> "is a number".  If we had a PyBaseNumber_Type to use here, it would
> be smooth, easy, and fast to check for it.

There shouldn't be a check at all. It should just start doing the
summing, and it will "work" if PyNumber_Add works for the individual
items. Of course, there is an education value of ruling out string
addition, since there is a better way to do that, and there should
be only one obvious way.

I see nothing wrong in summing up sequences, matrices, and arrayish
things, using sum.

> A fast rational number type, see http://gmpy.sourceforge.net for 
> details (gmpy wraps LGPL'd library GMP, and gets a lot of speed and 
> functionality thereby).

Ok, so mpq are rational numbers.

>> if the  parameter belongs to some algebraic ring homomorphic
>> with the real numbers, or some such. Are complex numbers also numbers?
>> Is it meaningful to construct gmpy.mpqs out of them? What about
>> Z/nZ?
> 
> 
> If I could easily detect "this is a number" about an argument x, I'd 
> then ask x to change itself into a float, so complex would be easily 
> rejected (while decimals would mostly work fine, although a bit  slowly
> without some specialcasing, due to the Stern-Brocot-tree  algorithm I
> use to build gmpy.mpq's from floats).  I can't JUST ask x  to "make
> itself into a float" (without checking for x's "being a  number")
> because that would wrongfully succeed for many cases such as  strings.

Hmm. If you want to do the generic conversion from numbers to rationals
by going through float, then this is what you should do. Convert to
float, and don't bother with checking whether it will succeed. Instead,
if the type conversion gives an error, just return that to the caller.

However, it also sounds odd that you are trying to do the
to-rational-with-arbitrary-precision conversion by going through
floats. Instead, if the argument is decimal, you really should
do the division by the approprate base of 10, no?

Regards,
Martin


More information about the Python-Dev mailing list