Chironex
Chironex

Reputation: 413

Create a python class that is treated as a list, but with more features?

I have a class called dataList. It is basically a list with some metadata---myDataList.data contains the (numpy) list itself, myDataList.tag contains a description, etc. I would like to be able to make myDataList[42] return the corresponding element of myDataList.data, and I would like for Numpy, etc. to recognize it as a list (I.E., numpy.asarray(myDataList) returns a numpy array containing the data in myDataList). In Java, this would be as easy as declaring dataList as implementing the List interface, and then just defining the necessary functions. How would you do this in Python?

Thanks.

Upvotes: 3

Views: 472

Answers (3)

jena
jena

Reputation: 8506

You can subclass list and provide additional methods:

class CustomList(list):
    def __init__(self, *args, **kwargs):
        list.__init__(self, args[0])

    def foobar(self):
        return 'foobar'

CustomList inherits the methods of Python's ordinary lists and you can easily let it implement further methods and/or attributes.

Upvotes: 8

Pushpak Dagade
Pushpak Dagade

Reputation: 6440

class mylist(list):
    def __init__(self, *args, **kwargs):
        super(mylist, self).__init__(*args, **kwargs)       # advantage of using super function is that even if you change the parent class of mylist to some other list class, like your numpy list class, you won`t have to change the remaining code, which is what you would have to do incase of jena`s code snippet.
        # whatever meta data you want to add, add here
        self.tag = 'some tag'
        self.id = 3

    # you can also add custom methods
    def foobar(self):
        return 'foobar'

Now, you can create instance of mylist and use them as normal lists, with your additional meta data.

>>> a = mylist([1,2,3,4])
>>> a
[1,2,3,4]
>>> a[2] = 3                  # access normal list features
>>> a.append(5)               # access normal list features
>>> a
[1,2,3,4,5]
>>> a.tag                     # your custom meta data
'some tag'
>>> a.id                      # your custom meta data
3
>>> a.foobar()                # your custom meta data
'foobar'
>>> a.meta1 = 'some more'     # you can even add more meta data on the fly (which you cannot do in a regular list class)
>>> a.meta1
'some more'                   # your new meta data

Upvotes: 3

phihag
phihag

Reputation: 287775

Define __len__, __getitem__, __iter__ and optionally other magic methods that make up a container type.

For example, a simplified range implementation:

class MyRange(object):
   def __init__(self, start, end):
       self._start = start
       self._end = end
   def __len__(self):
       return self._end - self._start
   def __getitem__(self, key):
       if key < 0 or key >= self.end:
           raise IndexError()
       return self._start + key
   def __iter__(self):
       return iter([self[i] for i in range(len(self))])

Upvotes: 2

Related Questions