[Python-Dev] basenumber redux (original) (raw)

"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 builtinsum uses C-coded typechecking to single out strings as an error case:

/* reject string values for 'start' parameter */ if (PyObjectTypeCheck(result, &PyBaseStringType)) { PyErrSetString(PyExcTypeError, "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 builtinsum 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 PyBaseNumberType 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