I implemented the __contains__
method on a class for the first time the other day, and the behavior wasn't what I expected. I suspect there's some subtlety to the in
operator that I don't understand and I was hoping someone could enlighten me.
It appears to me that the in
operator doesn't simply wrap an object's __contains__
method, but it also attempts to coerce the output of __contains__
to boolean. For example, consider the class
class Dummy(object):
def __contains__(self, val):
# Don't perform comparison, just return a list as
# an example.
return [False, False]
The in
operator and a direct call to the __contains__
method return very different output:
>>> dum = Dummy()
>>> 7 in dum
True
>>> dum.__contains__(7)
[False, False]
Again, it looks like in
is calling __contains__
but then coercing the result to bool
. I can't find this behavior documented anywhere except for the fact that the __contains__
documentation says __contains__
should only ever return True
or False
.
I'm happy following the convention, but can someone tell me the precise relationship between in
and __contains__
?
Epilogue
I decided to choose @eli-korvigo answer, but everyone should look at @ashwini-chaudhary comment about the bug, below.
in
should be consistent with return value of__contains__
– Whosoeverin
as I care about the design reasoning and apparent lack of documentaiton. If you post this answer, I will select your answer as the accepted one. – Theodoretheodoric