Implementing Membership Checks in Custom Classes
00:00
Now you’ve seen that membership checks in Python work across all sorts of data types. But what if you need something even more custom? You can also implement membership checks in your custom classes, and you do that by implementing the __contains__
method.
00:15
There’s also other ways, alternatively, you can implement __iter__
or __getitem__
, but __contains__
is essentially the membership check dunder method.
00:26
I’ll show you the difference between those but let’s head over to the IDE and code up a little custom class with __contains__
.
00:39
Here I have a new empty file that I called storehouse.py
, and here’s my boilerplate code that starts the class Storehouse
. I’m just defining an initializer method that takes .self
and wares
and then assigns .self.wares
to whatever wares
you put into the storehouse.
00:58
So as you can see, this is a way that your merchant friend may want to replace the dictionary that they’re using for their e-commerce store and instead keep track of their inventory in a custom class Storehouse
.
01:10 But of course, you need to make sure that the storehouse actually does what you need it to do, so in this case, that was membership checking first of all.
01:17
So let’s go ahead and try that out. I will create an instance of a Storehouse
storehouse
01:26
passing two items. Let’s put in goblet
and a rose
01:32
and then I’ll print()
to see whether the rose
is in storehouse
. For this, I’m typing, I call the print()
, so print(
and then I just type the string “rose” and the membership testing operator in
and then the name of the instance.
01:51
So now you just need to run this file. I’ll open a terminal and type python storehouse.py
, and you see that there’s an error because you can’t do membership checking on a custom object unless you implement it.
02:08
The error message may be a little bit misleading because currently it just tells you that Storehouse
is not iterable. So it doesn’t say anything specifically about membership testing, but instead refers to iteration, but you’ll look more into that in just a bit.
02:21 For now, we know that this is not the way to go,
02:25
so let’s get rid of this again and add some code to make membership testing work in your custom storehouse. So let’s go ahead and define the __contains__
method.
02:37
So I do two underscores, write contains
, and then another two underscores. And this will take .self
and then item
.
02:46 And here I’m just going to implement it by relying on the way that it’s implemented for whatever type of collection we’re going to use to represent that storehouse.
02:56
So I’ll just say return item in .self.wares
. So as you can see here I’m using another membership check that just checks on the collection that’s going to hold all the wares that you’re passing in.
03:09
But this is your custom storehouse so of course you could also implement some sort of a different logic within your __contains__
method. And now you can go ahead and instantiate a Storehouse
03:23
that takes some sort of a collection. I’m going to use a list here and I’ll say we put in a goblet
and a rose
, and now you’ll be able to perform membership checks on that. Actually, let’s instead try that out in the REPL.
03:41 So make sure the file is saved.
03:44 Open up a new Python REPL,
03:46
import storehouse from Storehouse, from
storehouse` import Storehouse
, and then create my Storehouse
instance.
03:58
You can see that storehouse
is a custom object of the class storehouse.Storehouse
, which means it comes from the module named storehouse
and it’s called Storehouse
.
04:10
Alright. And now you can do membership checks on this. You can say, is dagger
in the storehouse
? And Python returns False
.
04:21
Or is a rose
in the storehouse
? And Python returns True
. So by implementing __contains__
in your custom class, you made it possible to do membership checks on it, but you already know not all in
s are alike, so implementing the __contains__
does not make your class iterable.
04:43
So if you tried to say something like, for ware in storehouse: print(ware)
you’ll run into an error and it’s a TypeError
that tells you that Storehouse
object is not iterable.
04:58
So you can run membership checks on it if you implement __contains__
, but you can’t iterate over it. Implementing __contains__
doesn’t make your class iterable.
05:08 So what if you want that as well? Let’s take a look at the next lesson of an alternative way to implement both membership checking as well as iteration.
Become a Member to join the conversation.