Reputation: 8484
I have a multiple instances of a class. I consider two classes equal, when a certain attribute matches.
All instances are in an array list = [a, b, c]
. I now create a new instance of said class d
. When I do d in list
it ofc outputs false
.
My question is: How is membership checked when using in
? Is it normal comparison (which means I can use __eq__
in my class to implement the equality of classes)? If not: How can I achieve that in
matches if a certain attribute of a class equals?
Upvotes: 0
Views: 103
Reputation: 1151
class Foo:
def __init__(self, x):
self.x = x
def __eq__(self, other):
if isinstance(other, Foo):
return self.x == other.x
a = [1,2,3,Foo(4),Foo(5)]
Foo(5) in a
>>>True
Foo(3) in a
>>>False
Upvotes: 2
Reputation: 48100
Behavior of in
is based on the __contains__()
method. Let us see with an example:
class X():
def __contains__(self, m):
print 'Hello'
Now when you do in
on X()
m you can see 'Hello' printed
>>> x = X()
>>> 1 in x
Hello
False
As per the __contains__()
document:
For objects that don’t define
__contains__()
, the membership test first tries iteration via__iter__()
, then the old sequence iteration protocol via__getitem__()
, see this section in the language reference.
Upvotes: 1
Reputation: 16945
From the docs:
For user-defined classes which define the
__contains__()
method,x in y
is true if and only ify.__contains__(x)
is true.For user-defined classes which do not define
__contains__()
but do define__iter__()
, x in y is true if some value z withx == z
is produced while iterating over y. If an exception is raised during the iteration, it is as if in raised that exception.Lastly, the old-style iteration protocol is tried: if a class defines
__getitem__()
, x in y is true if and only if there is a non-negative integer index i such thatx == y[i]
, and all lower integer indices do not raiseIndexError
exception. (If any other exception is raised, it is as if in raised that exception).
Upvotes: 1