13

Is there a way to overload the equality operator __eq__(self, other) for a namedtuple in python?

I know this is possible in classes and redefining the method, but is this possible for a namedtuple as well, and how would you implement this?

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
EVR
  • 346
  • 2
  • 7

3 Answers3

19

I think, given the public API of namedtuple, it is not possible to do that without overriding. The shortest solution would be:

class Person(namedtuple('Person', ['ssn', 'name'])):
    def __eq__(self, other):
        return self.ssn == other.ssn

--

>>> p1 = Person("123", "Ozgur")
>>> p2 = Person("123", "EVR")
>>> print p1 == p2
True

Another option would be:

>>> Person = namedtuple('Person', ['ssn', 'name'])
>>> Person.__eq__ = lambda x, y: x.ssn == y.ssn
Ozgur Vatansever
  • 49,246
  • 17
  • 84
  • 119
6

You can't patch __eq__, as far as I'm aware, but you can subclass a namedtuple and implement it however you like on that. For example:

from collections import namedtuple

class Demo(namedtuple('Demo', 'foo')):

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

In use:

>>> d1 = Demo(1)
>>> d2 = Demo(1)
>>> d1 is d2
False
>>> d1 == d2
True
jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
5

With the new Namedtuple class from typing it is possible. It works for me with python 3.6 but could also work with previous examples.

For example:

from typing import NamedTuple

class A(NamedTuple):
    x:str
    y:str
    def __eq__(self,other):
        return self.x == other.x

print(A('a','b') == A('a','c'))
David Michael Gang
  • 7,107
  • 8
  • 53
  • 98