CZZ82
CZZ82

Reputation: 23

Override __add__method

I'm trying to override the __add__ method so that the duplicate will not be added. What went wrong with my code?

class Ulist(UserList):

    def __init__(self,value=[]):
        UserList.__init__(self)
        self.value = value

    def __add__(self,addvalue):
        for x in addvalue:
            if x in self.value:
                print("It already exists")
            else:
                return self.value.__add__(addvalue)

If Ulist=[1,2,3], and I do Ulist.__add__([3]), I am expecting a message of "it already exists". But I got [1,2,3,3].

Upvotes: 2

Views: 1771

Answers (2)

Mad Physicist
Mad Physicist

Reputation: 114280

Everything is an object in Python, including classes, modules, lists, etc. You access objects by the name they are bound to.

When you write class Ulist(UserList): ..., you bind a class object to the name Ulist. Since classes are regular objects, you can do something like

Vlist = Ulist
x = Vlist()

This will produce the same result as if you had called Ulist directly, since the first assignment just binds the class once to another name.

When you subsequently do Ulist = [1, 2, 3], you discard the class object that the name Ulist was originally bound to, and bind it to a list object instead. This is because an expression in square brackets is always interpreted as a plain list.

To create an instance of Ulist the class, you have to call the initializer:

x = Ulist([1, 2, 3])

Now the operation x + [3] should print what you originally expected. Note that you aren't normally supposed to call special methods like __add__ directly. Either use +, or more rarely, operator.add.

Another thing to keep in mind is that UserList already exposes the underlying list via the data attribute. Your value attribute is overkill at this point and actually prevents you from using all the other nice features of UserList. A better implementation would look something like

class Ulist(UserList):

    def __init__(self, value=[]):
        super().__init__(value)

    def __add__(self, addvalue):
        for x in addvalue:
            if x in self:
                print(f"{x!r} already exists")
            else:
                return super().__add__(addvalue)

All in all, though, what you are probably looking for is set.

Upvotes: 1

Chetan Ameta
Chetan Ameta

Reputation: 7896

you have initialize Ulist as variable so it will act as object of list:

to work with your code you need to instantiate the object of the class, see below example

class Ulist():

    def __init__(self, value=[]):

        self.value = value

    def __add__(self, addvalue):
        for x in addvalue:
            if x in self.value:
                print("It already exists")
            else:
                return self.value.__add__(addvalue)


o = Ulist(value=[1, 2, 3])

o.__add__([3])

print o.value

output

It already exists
[1, 2, 3]

Upvotes: 0

Related Questions