qasfux
qasfux

Reputation: 207

Create a subclass of list without deep copy

I want to subclass list to add some function to it, for example, my_func.

Is there a way to do this without copying the whole list, i.e. make a shallow copy, on the creation of the MyList object and let MyList reference the same list as the one used to construct it?

class MyList(list):
    def my_func(self):
        # do some stuff
        return self


l1 = list(range(10))
l2 = MyList(l1)

print(l1)
print(l2)

l1[3] = -5

print(l1)
print(l2)

Upvotes: 4

Views: 394

Answers (1)

Dimitris Fasarakis Hilliard
Dimitris Fasarakis Hilliard

Reputation: 160687

Pretty sure this isn't possible with a list subclass. It is possible with a collections.UserList subclass (simply UserList in Python 2):

from collections import UserList

class MyList(UserList):

    def __init__(self, it=None):
        # keep reference only for list instances
        if isinstance(it, list):
            self.data = it
        else:
            super().__init__(it)

    def my_func(self):
        # do some stuff
        return self

The fact that UserList exposes a data attribute containing the actual list instance makes it easy for us to replace it with the iterable it and essentially just drop the supplied argument there and retain the reference:

By initializing as you did:

l1 = list(range(10))
l2 = MyList(l1)

print(l1, l2, sep='\n')
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

and then mutating:

l1[3] = -5

The data attribute referencing l1 is, of course, mutated:

print(l1, l2, sep='\n')
[0, 1, 2, -5, 4, 5, 6, 7, 8, 9]
[0, 1, 2, -5, 4, 5, 6, 7, 8, 9]

Upvotes: 4

Related Questions