0

How does __contains__ work? For example I have a class MyClass and an instance of this class called a, when I write if val in a: I'm basically invoking __contains__, from my understanding, if __contains__ is not implemented in the class then __iter__ is invoked, which iterates between the list returned by __getitem__ (which in my example is implemented in the class) and if val is equal to some element of the list then __contains__ returns True. Is it right?

EDIT: __getitem__ in my code only returns the element of the list at a given position so I don't know how would that work together with __iter__

user14095422
  • 79
  • 1
  • 7

2 Answers2

2

I think the __contains__ document is clear enough,

> Called to implement membership test operators. Should return true if
> item is in self, false otherwise. For mapping objects, this should
> consider the keys of the mapping rather than the values or the
> key-item pairs.
> 
> 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.
M--
  • 25,431
  • 8
  • 61
  • 93
Dyno Fu
  • 8,753
  • 4
  • 39
  • 64
  • "Should return true if item is in self" so it checks every attribute of the instance of the class and if it finds that one attribute has the value "val" then it returns true? – user14095422 Aug 13 '20 at 20:00
  • i don't think it will check object attributes (or it's dictionary). (x.a) x has a attribute a, does not mean `a in x`. – Dyno Fu Aug 13 '20 at 20:49
  • roughly `in` is only meaningful (defined) when the object can be considered as a container class (dict, sequence etc). – Dyno Fu Aug 13 '20 at 20:51
  • by dictionary i mean [`__dict__`](https://docs.python.org/3/library/stdtypes.html#object.__dict__) – Dyno Fu Aug 13 '20 at 21:02
1

That's exactly right. More specifics here:

For user-defined classes which define the contains() method, x in y returns True if y.contains(x) returns a true value, and False otherwise.

For user-defined classes which do not define contains() but do define iter(), x in y is True if some value z, for which the expression x is z or x == z is true, 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 that x is y[i] or x == y[i], and no lower integer index raises the IndexError exception. (If any other exception is raised, it is as if in raised that exception).

M--
  • 25,431
  • 8
  • 61
  • 93
funyuns
  • 229
  • 1
  • 9
  • if only "__getitem__" is implemented, when i invoke "__contains__", does it also use "__len__" to know the maximum index possible? otherwise, i don't know how the program would stop – user14095422 Aug 13 '20 at 20:06
  • Not sure what you're referring to with the 'because "you" wrote "true" '. However, I was not trying to plagiarize or claim the information, but rather lay out the information here from the docs. The link was not included properly. It's there now. – funyuns Aug 13 '20 at 20:32
  • I see. Well, I do say true/false in all my writing. But thanks for pointing this out – I'll be sure to make sure everything is properly credited going forward. – funyuns Aug 13 '20 at 20:53