Reputation: 207
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
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