If I understand correctly, the __cmp __ () function of an object is called to evaluate all the objects in the collection when determining whether the object is a member or "in" a collection. However, this is not like many:
class MyObject(object): def __init__(self, data): self.data = data def __cmp__(self, other): return self.data-other.data a = MyObject(5) b = MyObject(5) print a in [b] //evaluates to True, as I'd expect print a in set([b]) //evaluates to False
How is the membership of an object in a set checked, then?
>>> xs = [] >>> set([xs]) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unhashable type: 'list'
. , dicts. ( - O (1), ), : , , (, ) .
__hash__ id ( imho), , object __hash__, (, sizeof ).
__hash__
id
object
sizeof
__hash__ :
class MyObject(object): def __init__(self, data): self.data = data def __cmp__(self, other): return self.data - other.data def __hash__(self): return hash(self.data) a = MyObject(5) b = MyObject(5) print a in [b] # True print a in set([b]) # Also True!
, __hash__, id , , , __hash__, , , .
The set uses a dict backstage, so the in operator checks to see if the object exists as a key in the dict. Since your object does not implement a hash function, the default hash function for objects uses the object identifier. Thus, even if a and b are equivalent, they are not the same object, and that is being tested.