Kinder9211
Kinder9211

Reputation: 155

__eq__ method to compare two custom objects with list

I have a python class that contains a list of strings. I want to compare two instances of this class. However, I noticed that if my class gets large the comparison gets quite cumbersome to write. Is there an easier way to write the __eq__ method than this? I use a List instead of a Set because I want to fill this class with data from JSON at a later stage.

json_one = {"var_one": "hello", "var_two": ["foo", "bar"]}
json_two = {"var_one": "hello", "var_two": ["bar", "foo"]}

@dataclass
class Test:
    var_one: str
    var_two: List[str]

    def __eq__(self, other):
        if isinstance(other, Test):
            return self.var_one == other.var_one\
                   and sorted(self.var_two) == sorted(other.var_two)
        return False


test_one = Test(**json_one)
test_two = Test(**json_two)

if test_one == test_two:
    print("yay we're equal with lists in different order")

Upvotes: 1

Views: 1720

Answers (1)

chepner
chepner

Reputation: 531115

The fact that you can define an instance of your class using the output of json.load should not dictate your class's design. Rather, define your class "naturally", and provide a method for using a JSON response to create the instance.

from dataclasses import dataclass
import json

@dataclass
class Test:
    # Emphasize the independence of your class from any particular JSON object
    str1: str
    set_of_str1: set[str]

    @classmethod
    def from_json(cls, s):
        d = json.loads(s)
        return cls(d['var_one'], set(d['var_two']))


assert Test("foo", set(["bar", "baz"])) == \
        Test.from_json('{"var_one": "foo", "var_two": ["baz", "bar"]}')

Upvotes: 3

Related Questions