David542
David542

Reputation: 110163

How to support the `in` operation in python with a class

What magic method do I have to modify to support the in operator. Here's an example of what I'm trying to do:

class DailyPriceObj:
    def __init__(self, date, product_id=None):
        self.date = date
        self.product_id = product_id
        self.sd_buy = None

l = list()
l.append(DailyPriceObj(date="2014-01-01"))
DailyPriceObj(date="2014-01-01") in l # how to get this to return True?

In other words, I want my object to "act like" the date property, so I can use that to see if that obj is in an interable (date should be a unique field here).

Upvotes: 3

Views: 1344

Answers (2)

Dani Mesejo
Dani Mesejo

Reputation: 61910

You need to implement __eq__ (and __hash__ for the sake of completeness):

class DailyPriceObj:
    def __init__(self, date, product_id=None):
        self.date = date
        self.product_id = product_id
        self.sd_buy = None

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.date == other.date

    def __hash__(self):
        return hash(self.date)


l = [DailyPriceObj(date="2014-01-01")]
s = {DailyPriceObj(date="2014-01-01")}

print(DailyPriceObj(date="2014-01-01") in l)
print(DailyPriceObj(date="2014-01-01") in s)

Output

True
True

From the documentation on __hash__:

Called by built-in function hash() and for operations on members of hashed collections including set, frozenset, and dict. __hash__() should return an integer. The only required property is that objects which compare equal have the same hash value; it is advised to mix together the hash values of the components of the object that also play a part in comparison of objects by packing them into a tuple and hashing the tuple.

Upvotes: 5

sanyassh
sanyassh

Reputation: 8510

You can implement __eq__ in such a way that both two ways of checking will work:

class DailyPriceObj:
    def __init__(self, date, product_id=None):
        self.date = date
        self.product_id = product_id
        self.sd_buy = None

    def __eq__(self, other):
        return self.date == other

l = list()
l.append(DailyPriceObj(date="2014-01-01"))
# both ways work:
print(DailyPriceObj(date="2014-01-01") in l)  # True
print("2014-01-01" in l)  # True

Upvotes: 1

Related Questions