2011-07-03 29 views
21

chciałbym napisać klasę niestandardową listę w Pythonie (nazwijmy go MyCollection), gdzie mogę w końcu zadzwonić:Jak utworzyć niestandardową klasę list w python?

for x in myCollectionInstance: 
    #do something here 

Jak bym się do tego zabrać? Czy jest jakaś klasa, którą muszę rozszerzyć, czy też są jakieś funkcje, które muszę zastąpić, aby to zrobić?

+0

Czy mógłbyś lepiej wyjaśnić swoje wymagania? Jeśli podklasujesz jakąkolwiek klasę iterowalną (lista, dict, itp.) To powinna działać bez problemów. Ale może czegoś brakuje? – mac

+0

@mac: Jeśli podklasyę klasy iterowalnej, chciałbym również sposób, aby móc uzyskać dostęp do obiektu listy podstawowej, tak, że mogę zapewnić dodatkowe funkcje, które działają na nim. Nie chcę pary klucz-wartość (dict), więc wystarczy coś, co emuluje indeksowaną kolekcję (listę). –

Odpowiedz

25

Twój może podklasy list jeśli kolekcja zasadzie zachowuje się jak listy:

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

Jednakże, jeśli głównym pragnieniem jest to, że kolekcja obsługuje protokół iterator, wystarczy, aby zapewnić __iter__ metoda:

class MyCollection(object): 
    def __init__(self): 
     self._data = [4, 8, 15, 16, 23, 42] 

    def __iter__(self): 
     for elem in self._data: 
      yield elem 

pozwala to na iteracyjne nad każdą instancję MyCollection.

+1

Myślę, że podpis Twojej super metody jest błędna (tylko 99% pewności, ale nie "list()" akceptuje tylko jeden iterowalny jako argument? Czy jest też specjalny powód dla ostatniej dwukropka w wywołaniu 'super'? ? – mac

+1

Tak, oczywiście masz rację, edytowałem kod ... Dzięki za podpowiedź – jena

3

Można rozszerzyć klasę list:

class MyList(list): 

    def __init__(self, *args): 
     super(MyList, self).__init__(args[0]) 
     # Do something with the other args (and potentially kwars) 

Przykład użycia:

a = MyList((1,2,3), 35, 22) 
print(a) 
for x in a: 
    print(x) 

oczekiwany wynik:

[1, 2, 3] 
1 
2 
3 
10

lubię podklasy MutableSequence, jak recommended by Alex Martelli. To działa dobrze, szczególnie gdy muszę dodać niestandardowe metody do listy, którą buduję.

from collections import MutableSequence 

class MyList(MutableSequence): 
    """A container for manipulating lists of hosts""" 
    def __init__(self, data=None): 
     """Initialize the class""" 
     super(MyList, self).__init__() 
     if (data is not None): 
      self._list = list(data) 
     else: 
      self._list = list() 

    def __repr__(self): 
     return "<{0} {1}>".format(self.__class__.__name__, self._list) 

    def __len__(self): 
     """List length""" 
     return len(self._list) 

    def __getitem__(self, ii): 
     """Get a list item""" 
     return self._list[ii] 

    def __delitem__(self, ii): 
     """Delete an item""" 
     del self._list[ii] 

    def __setitem__(self, ii, val): 
     # optional: self._acl_check(val) 
     self._list[ii] = val 

    def __str__(self): 
     return str(self._list) 

    def insert(self, ii, val): 
     # optional: self._acl_check(val) 
     self._list.insert(ii, val) 

    def append(self, val): 
     self.insert(len(self._list), val) 

if __name__=='__main__': 
    foo = MyList([1,2,3,4,5]) 
    foo.append(6) 
    print foo # <MyList [1, 2, 3, 4, 5, 6]> 
+4

'jeśli nie (dane to Brak):' to nie tak, jak piszesz swój kod Pythona, dopóki nie jesteś Wielkim Mistrzem Jedi. 'Jeśli dane nie są żadne "- to wygląda dobrze. – byashimov

Powiązane problemy