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