Syntax and Definition
object.__contains__(self, element)
The Python __contains__()
magic method implements the membership operation, i.e., the in
keyword. Semantically, the method returns True
if the argument object exists in the sequence on which it is called, and False
otherwise. For example, 3 in [1, 2, 3]
returns True
as defined by the list method [1, 2, 3].__contains__(3)
.
We call this a “Dunder Method” for “Double Underscore Method” (also called “magic method”). To get a list of all dunder methods with explanation, check out our dunder cheat sheet article on this blog.
Basic Example Overriding Membership
You can overload the “in
” operator by overriding the __contains__(self, item)
method and return a Boolean value True
or False
whether the item exists in the custom class object or not.
Here’s a generalized example:
class MyClass: def __init__(self, my_collection): self.my_collection = my_collection def __contains__(self, item): return item in self.my_collection my = MyClass('hello world') print('hello' in my) # True
The custom class MyClass
wouldn’t generally support membership. But by defining the __contains__()
“dunder” method, you can reduce membership of an object in the class to the problem of checking membership of an object in a collection using the “in
” operator. Now, you can check, for example, if a string is a member of a custom class object.
Python Membership Background
Membership Without __contains__()
But what if the __contains__()
dunder method is not defined?
In this case, Python falls back to the __iter__()
iterator method to iterate over the object and compare each element individually using the ==
operator.
In the following example, you create a custom class Data
and overwrite the __init__()
, __iter__()
, and __next__()
methods so that you can create your own iterator over a Data
object.
Then, you attempt to check membership on this custom object—it works!
See the highlighted code part:
class Data: def __init__(self, data): self.data = data # an iterable def __iter__(self): self.current_index = 0 return self def __next__(self): if self.current_index < len(self.data): x = self.data[self.current_index] self.current_index += 1 return x raise StopIteration my_sequence = Data(['Alice', 'Bob', 'Carl']) print('Chris' in my_sequence) # False print('Alice' in my_sequence) # True
To improve your basic Python understanding, feel free to check out this related video on the iter()
built-in function: