How do I make an __eq__method to compare a class with 4 init variables?

Question:

I have the following class:

class Building():
   def __init__(self, item1, item2, item3, item4):
       self._item1 = item1
       self._item2 = item2
       self._item3 = []
       self._item3.append(item3)
       self._item4 = []
       self._item4.append(item4)

  def __eq__(self, building2):

Item1 and item2 are both int values, item3 and item4 are both lists that contain 1 item at the start with more added later possibly. How do I compare two building classes such that building1 == building2 would return true or false.

Edit: thanks for the feedback everyone, I have taken what everyone has said and changed my code it is much better now thanks!

Asked By: K Gaming

||

Answers:

def __eq__(self, building2):
  result1 = self.item1 == building2.item1
  result2 = self.item2 == building2.item2
  result3 = self.item3[0] == building2.item3[0]
  result4 = self.item4[0] == building2.item4[0]
  return result1 and result2 and result3 and result4
Answered By: olegario

Generate two tuples and compare them:

def __eq__(self, building2):
    return (self._item1, self._item2, self._item3, self._item4) == (
        building2._item1, building2._item2, building3._item1, building4._item1)
Answered By: Daniel

You can build tuples of those attributes that you want to compare, then compare those tuples. Make sure to check if the other object is actually a Building to avoid raising an AttributeError

def __eq__(self, other):
    if not isinstance(other, Building):
        return False
    self_attrs = (self._item1, self._item2, self._item3, self._item4)
    other_attrs = (other._item1, other._item2, other._item3, other._item4)
    return self_attrs == other_attrs
Answered By: Patrick Haugh

You can create an attribute _items in your __init__ with

self._items = self._item1, self._item2, self._item3, self._item4

and then define __eq__ as

def __eq__(self, other):
    return self._items == other._items
Answered By: taras

You can use builtin vars() to compare object’s dictionaries:

class Building():
    def __init__(self, item1, item2, item3, item4):
        self._item1 = item1
        self._item2 = item2
        self._item3 = []
        self._item3.append(item3)
        self._item4 = []
        self._item4.append(item4)

    def __eq__(self, building2):
        if not isinstance(building2, Building):
            return False
        return vars(self) == vars(building2)

b1 = Building(1, 2, 3, 4)
b2 = Building(1, 2, 3, 4)
b3 = Building(1, 2, 3, 3)
print(b1 == b2)
print(b1 == b3)

Outputs:

True
False
Answered By: Andrej Kesely

in eq you should use type(self) == type(other) instead of isinstance(other, self_class_name):

def __eq__(self, other):
    return (type(self), vars(self)) == (type(other), vars(other))

Try to run:

class Person:
    def __init__(self, name='Guido', surname='van Rossum'):
        self.name = name
        self.surname = surname

class Student(Person):
    __slots__ = 'university'
    def __init__(self, university='University of Amsterdam',**kwargs):
        super().__init__(**kwargs)
        self.university = university

p = Person()
s = Student()
print(isinstance(s, Person))
print(vars(p) == vars(s))
Answered By: Korney Chervonenko
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.