2011-06-23 52 views
3

我有一個名爲dataList的類。它基本上是一個包含元數據的列表 - myDataList.data包含(numpy)列表本身,myDataList.tag包含描述等。我希望能夠使myDataList [42]返回myDataList的相應元素。數據,我希望Numpy等將它識別爲列表(IE,numpy.asarray(myDataList)返回一個包含myDataList中數據的numpy數組)。在Java中,這將和將dataList聲明爲實現List接口一樣簡單,然後只需定義必要的函數。你將如何在Python中做到這一點?創建一個被視爲列表的Python類,但具有更多功能?

謝謝。

+5

你有沒有考慮直接對numpy.ndarray進行子類化?這裏似乎有一個很好的概述/教程在這個主題:http://docs.scipy.org/doc/numpy/user/basics.subclassing.html – matt

+0

@matt - 如果你提交作爲答案,我會爲它投票。 。 。 – JoshAdel

+0

@matt - 剛試過這個,它給了我一個令人沮喪的錯誤:當我繼承numpy.ndarray並創建一個新的dataList對象(我編寫了自己的構造函數)時,出現錯誤:「TypeError:需要整數」。我假設我無法覆蓋numpy.ndarray的構造函數?我怎麼做? – Chironex

回答

8

你也可以繼承列表,並提供額外的方法:

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

    def foobar(self): 
     return 'foobar' 

CustomList繼承Python的普通列表的方法,你可以很容易地讓它實現其他方法和/或屬性。

+0

好主意!我應該用我的代碼來處理類似的問題。 – weronika

2

定義__len__,__getitem__,__iter__以及可選的構成container type的其他魔術方法。

例如,簡化range實現:

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))]) 
3
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' 

現在,您可以創建mylist的實例,並將它們作爲普通列表與您的其他元數據一起使用。

>>> 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 
相關問題