Re: Interesting list Validity (True/False)
- From: "Gabriel Genellina" <gagsl-py2@xxxxxxxxxxxx>
- Date: Tue, 15 May 2007 21:07:52 -0300
En Tue, 15 May 2007 14:01:20 -0300, mensanator@xxxxxxx <mensanator@xxxxxxx> escribió:
On May 15, 12:30 am, "Gabriel Genellina" <gagsl-...@xxxxxxxxxxxx>
wrote:
And said section 5.9 should be updated too: "The objects need not have the
same type. If both are numbers or strings, they are converted to a common
type.
Except when they aren't.
I think you don't get the difference between a builtin object, fully under the Python developers' control, and a user defined class that can behave arbitrarily at wish of its writer and for which the Python documentation barely can say a word.
The docs say how will the Python interpreter try to compare objects (invoke the rich comparison methods, invoke __cmp__, etc) and how the *builtin* objects behave. For other objects, it's up to the object *writer* to provide such methods, and he can do whatever he wishes:
py> class Reversed(int):
.... def __lt__(self, other): return cmp(int(self),other)>0
.... def __gt__(self, other): return cmp(int(self),other)<0
.... def __le__(self, other): return cmp(int(self),other)>=0
.... def __ge__(self, other): return cmp(int(self),other)<=0
....
py>
py> j=Reversed(6)
py> j==6
True
py> j>5
False
py> j>10
True
py> j<=5
True
You can't blame Python for this.
Trueimport gmpy
a = 2**177149-1
b = gmpy.mpz(2**177149-1)
a==b
print '%d' % (b)
Traceback (most recent call last):
File "<pyshell#4>", line 1, in <module>
print '%d' % (b)
TypeError: int argument required
So although the comparison operator is smart enough to realize
the equivalency of numeric types and do the type conversion,
the print statement isn't so smart.
This is up to the gmpy designers/writers/maintainers. Anyone writing a class chooses which features to implement, which ones to omit, how to implement them, etc. The code may contain bugs, may not be efficient, may not behave exactly as the users expect, may not have anticipated all usage scenarios, a long etc. In this case, probably the gmpy writers have chosen not to allow to convert to int, and they may have good reasons to not do that (I don't know what platform are you working in, but I feel that your b object is somewhat larger than sys.maxint...).
Otherwise, objects of different builtin types always compare
unequal, and are ordered consistently but arbitrarily. You can control
comparison behavior of objects of non-builtin types by defining a __cmp__
method or rich comparison methods like __gt__, described in section 3.4."
I hope this helps a bit. Your performance issues don't have to do with the
*definition* of equal or not equal,
I didn't say that, I said the performance issues were related
to type conversion. Can you explain how the "definition" of
equal does not involve type conversion?
There is no type conversion involved for user defined classes, *unless* the class writer chooses to do so.
Let's invent some new class Number; they can be added and have basic str/repr support
py> class Number(object):
.... def __init__(self, value): self.value=value
.... def __add__(self, other): return Number(self.value+other.value)
.... def __str__(self): return str(self.value)
.... def __repr__(self): return 'Number(%s)' % self.value
....
py> x = Number(2)
py> y = Number(3)
py> z = x+y
py> z
Number(5)
py> z == 5
False
py> 5 == z
False
py> z == Number(5)
False
py> int(z)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: int() argument must be a string or a number
py> "%d" % z
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: int argument required
You can't compare them to anything, convert to integer, still nothing. Let's add "int conversion" first:
py> Number.__int__ = lambda self: int(self.value)
py> int(z)
5
py> "%d" % z
'5'
py> z == 5
False
py> 5 == z
False
Ok, a Number knows how to convert itself to integer, but still can't be compared successfully to anything. (Perhaps another language would try to convert automagically z to int, to compare against 5, but not Python).
Let's add basic comparison support:
py> Number.__cmp__ = lambda self, other: cmp(self.value, other.value)
py> z == Number(5)
True
py> z > Number(7)
False
py> z == z
True
py> z == 5
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 1, in <lambda>
AttributeError: 'int' object has no attribute 'value'
Now, a Number can be compared to another Number, but still not compared to integers. Let's make the comparison a bit smarter (uhm, I'll write it as a regular function because it's getting long...)
py> def NumberCmp(self, other):
.... if isinstance(other, Number): return cmp(self.value, other.value)
.... else: return cmp(self.value, other)
....
py> Number.__cmp__ = NumberCmp
py> z == 5
True
py> z == 6
False
py> 5 == z
True
As you can see, until I wrote some code explicitely to do the comparison, and allow other types of comparands, Python will not "convert" anything. If you find that some class appears to do a type conversion when comparing instances, it's because the class writer has explicitely coded it that way, not because Python does the conversion automagically.
only with how someone decided to write the mpz class.I'm beginning to think there's a problem there.
Yes: you don't recognize that gmpy is not a builtin package, it's an external package, and its designers/writers/implementors/coders/whatever decide how it will behave, not Python itself nor the Python developers.
--
Gabriel Genellina
.
- Follow-Ups:
- Re: Interesting list Validity (True/False)
- From: Alex Martelli
- Re: Interesting list Validity (True/False)
- From: mensanator@xxxxxxx
- Re: Interesting list Validity (True/False)
- References:
- Interesting list Validity (True/False)
- From: nufuhsus
- Re: Interesting list Validity (True/False)
- From: mensanator@xxxxxxx
- Re: Interesting list Validity (True/False)
- From: nufuhsus
- Re: Interesting list Validity (True/False)
- From: mensanator@xxxxxxx
- Re: Interesting list Validity (True/False)
- From: Carsten Haese
- Re: Interesting list Validity (True/False)
- From: mensanator@xxxxxxx
- Re: Interesting list Validity (True/False)
- From: Carsten Haese
- Re: Interesting list Validity (True/False)
- From: mensanator@xxxxxxx
- Re: Interesting list Validity (True/False)
- From: Steven D'Aprano
- Re: Interesting list Validity (True/False)
- From: mensanator@xxxxxxx
- Re: Interesting list Validity (True/False)
- From: Steven D'Aprano
- Re: Interesting list Validity (True/False)
- From: mensanator@xxxxxxx
- Re: Interesting list Validity (True/False)
- From: Carsten Haese
- Re: Interesting list Validity (True/False)
- From: mensanator@xxxxxxx
- Re: Interesting list Validity (True/False)
- From: Gabriel Genellina
- Re: Interesting list Validity (True/False)
- From: mensanator@xxxxxxx
- Interesting list Validity (True/False)
- Prev by Date: Re: Python Newbie Suggestions
- Next by Date: RE: Trying to choose between python and java
- Previous by thread: Re: Interesting list Validity (True/False)
- Next by thread: Re: Interesting list Validity (True/False)
- Index(es):
Relevant Pages
|