Home > other >  in-place append while subclassing a list in Python
in-place append while subclassing a list in Python

Time:07-05

I'd like to subclass the list object in Python, and add a method similar to the append method as well. I call it append_ in the below example

class MyList(list):
    def append_(self, element):
        new_list = list(self)
        new_list.append(element)
        self = self.__class__(new_list)
        return self

This is quite a simple example, but here is my problem: suppose I instantiate an object my_list with some list, and then I try to append an extra element to my_list

my_list = MyList(list(range(5)))
my_list.append_(6) # returns [0,1,2,3,4,6]
# BUT 
my_list # returns [0,1,2,3,4]

so at the end I appended nothing. I do not understand neither what goes wrong nor where I may find help for this problem ...

I'm working with Python 3.9.12, if it helps...

CodePudding user response:

There does not seem to have a problem with the code as i am able to run it properly

Works with repl

maybe try to put the code in a new file

The "_" was the problem

CodePudding user response:

Oh, I finally tried one more thing:

class MyList(list):
    def append_(self, element):
        new_list = list(self)
        new_list.append(element)
        self.__init__(new_list)
        return self

that finally works as desired. I'm not sure I understand why, though, so I'd be glad if someone wants to elaborate more on this working solution :-)

CodePudding user response:

As your append_() function includes an underscore at the end of its name, you won't be appending anything to your list object when invoking it. So to get the correct result, you need to use append() without underscore:

class MyList(list):
    def append_(self, element):
        new_list = list(self)
        new_list.append(element)
        self = self.__class__(new_list)
        return self

my_list = MyList(list(range(5)))
print(my_list)
print(my_list.append(6))
print(my_list)

Output:

[0, 1, 2, 3, 4]
None
[0, 1, 2, 3, 4, 6]

In contrast, when you run the code with the function inside the class:

class MyList(list):
    def append_(self, element):
        new_list = list(self)
        new_list.append(element)
        self = self.__class__(new_list)
        return self

my_list = MyList(list(range(5)))
print(my_list)
print(my_list.append_(6))
print(my_list)

It prints the wrong output, not modifying the list:

[0, 1, 2, 3, 4]
[0, 1, 2, 3, 4, 6]
[0, 1, 2, 3, 4]

Also, you can change the append_() function to get the desired functionality:

class MyList(list):
    def append_(self, element):
        self.append(element)

my_list = MyList(list(range(5)))
print(my_list)
print(my_list.append_(6))
print(my_list)

Output:

[0, 1, 2, 3, 4]
None
[0, 1, 2, 3, 4, 6]
  • Related