Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Equality overloading for namedtuple

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?

like image 943
EVR Avatar asked Jan 02 '16 21:01

EVR


People also ask

Can you modify a Namedtuple?

Since a named tuple is a tuple, and tuples are immutable, it is impossible to change the value of a field. In this case, we have to use another private method _replace() to replace values of the field. The _replace() method will return a new named tuple.

Can you subclass Namedtuple?

Python's namedtuple() is a factory function available in collections . It allows you to create tuple subclasses with named fields. You can access the values in a given named tuple using the dot notation and the field names, like in obj. attr .

Can you pickle a Namedtuple?

@Antimony: pickle handles namedtuple classes just fine; classes defined in a function local namespace not so much.

How do we need to import Namedtuple?

To create a named tuple, import the namedtuple class from the collections module. The constructor takes the name of the named tuple (which is what type() will report), and a string containing the fields names, separated by whitespace. It returns a new namedtuple class for the specified fields.


2 Answers

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'))
like image 132
David Michael Gang Avatar answered Oct 07 '22 05:10

David Michael Gang


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
like image 29
Ozgur Vatansever Avatar answered Oct 07 '22 03:10

Ozgur Vatansever