Chcę utworzyć klasę w języku Python z różnymi atrybutami i metodami, ale aby dziedziczyła ona funkcjonalność listy, dzięki czemu mogę dołączać obiekty do samego obiektu, a nie do jego atrybutów. Chcę móc powiedzieć "graph[3]
" zamiast "graph.node_list[3]
". Czy jest jakiś sposób na zrobienie tego?Jak utworzyć klasę, która również jest listą?
Odpowiedz
Wszystko, co naprawdę trzeba zrobić, to zapewnić __getitem__
In [1]: class Foo:
...: def __init__(self, *args):
...: self.args = args
...: def __getitem__(self, i):
...: return self.args[i]
...:
In [2]: c = Foo(3,4,5)
In [3]: c[2]
Out[3]: 5
In [4]: c[3]
IndexError: tuple index out of range #traceback removed for brevity
In [5]: for i in c: print(i) #look, ma, I can even use a for-loop!
3
4
5
Uzupełnienie: Istnieją inne metody prawdopodobnie chcesz, aby zapewnić, too. __len__
jest zdecydowanie jednym z nich. Jest dość długa lista magicznych metod, polecam je przejrzeć i wybrać te, które mają sens.
Można również czerpać z' abc.Sequence', aby poprawić sprawdzanie typu. Lub przynajmniej zaimplementuj '__len__' ... – refi64
@ kirbyfan64sos, Dzięki podklasie wirtualnej, nie musisz dziedziczyć z żadnego z' zbiorów' 'abc, chyba że chcesz dziedziczyć swoje metody. – Navith
@Navith Miałem na myśli sprawdzanie typu, takie jak Mypy. :) – refi64
Chcesz dodać specjalne metody, takie jak __getitem__
w przypadku list. Spójrz na:
https://docs.python.org/2/reference/datamodel.html#emulating-container-types
można tylko dziedziczyć list
:
class Foo(list):
def __init__(self):
pass
Ale instacji wbudowanych typów niekoniecznie jest dobrym pomysłem.
collections.abc.Sequence
(lub od 3,5, typing.Sequence[T]
) jest sposób, by to zrobić.
Ponieważ Python używa duck typing, podstawową różnicą między listą a jakimkolwiek innym obiektem jest zestaw metod, które on eksponuje. Możesz łatwo zobaczyć podstawowe elementy (metody i pola) obiektu za pomocą funkcji dir()
.
>>> [a for a in dir([]) if callable(getattr([], a))]
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__',
'__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__',
'__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__',
'__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__',
'__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index',
'insert', 'pop', 'remove', 'reverse', 'sort']
Oczywiście jest tu wiele metod i prawdopodobnie nie dba się o większość z nich. Ale jeśli twoim celem było naprawdę powielać zachowanie listy, prawdopodobnie chcesz je zaimplementować. Większość metod __...__
jest zdefiniowanych w Pythonie data model, jeśli chcesz je sprawdzić.
Od tej strony:
Zmienne sekwencje powinny dostarczyć metod
append()
,count()
,index()
,extend()
,insert()
,pop()
,remove()
,reverse()
isort()
, jak Python Standardowa lista obiektów. Na koniec, typy sekwencji powinny implementować dodawanie (czyli konkatenację) i mnożenie (co oznacza powtarzanie) przez definiowanie opisanych poniżej metod; nie powinni definiować innych operatorów numerycznych. Zaleca się, aby oba odwzorowania i sekwencje implementowały metodę__contains__()
, aby umożliwić efektywne wykorzystanie operatora in; dla odwzorowań, w powinno przeszukiwać klucze mapowania; dla sekwencji, powinien przeszukać wartości. Ponadto zaleca się, aby oba odwzorowania i sekwencje implementowały metodę__iter__()
, aby umożliwić wydajną iterację przez pojemnik; dla odwzorowań,__iter__()
powinno być takie samo jak keys(); w przypadku sekwencji powinien on iterować przez wartości.
Funkcja, o którą pytasz w szczególności, wyszukiwanie indeksu, jest dostępna pod numerem __getitem__
. Sugerowałbym również wdrożenie co najmniej __contains__()
i __iter__()
(i może __len__()
).
- 1. Jak utworzyć klasę, która buforuje obiekty?
- 2. jQuery - usunąć klasę, która jest w tablicy
- 3. Jak poprawnie utworzyć klasę narzędzia?
- 4. Python liczy elementy w wartości dyktowanej, która jest listą
- 5. Czy istnieje kolejka (PriorityQueue), która jest również zestawem?
- 6. Jak utworzyć listę z listą <enum>?
- 7. Jak utworzyć klasę współpracującą z programem TransactionScope?
- 8. Jak utworzyć klasę Python w C?
- 9. Jednostka testująca klasę, która używa licznika czasu
- 10. Jak powiązać repeater z Listą <Person>, aby również zaktualizować powiązane elementy? (2-way)
- 11. W jaki sposób zmieniasz klasę, która jest ciągle edytowana?
- 12. Jak mogę napisać monadę stanu, która również obsługuje błędy?
- 13. Jak utworzyć niestandardową klasę list w python?
- 14. Czy można utworzyć mapę z listą kluczy?
- 15. Jak utworzyć klasę z zagnieżdżonymi obiektami Działka
- 16. Jak utworzyć abstrakcyjną klasę Haystack SearchIndex
- 17. Jak utworzyć klasę swift dla kategorii?
- 18. Jak programowo utworzyć niestandardową klasę widoku?
- 19. Iteracja przez klasę konkretnego div, która jest wewnątrz innego div
- 20. Jak utworzyć klasę Java, która implementuje jeden interfejs z dwoma rodzajami generycznymi?
- 21. Jak utworzyć klasę, która akceptuje nazwę pliku i może wydrukować jej zawartość?
- 22. W Kotlin, jak mogę rozszerzyć klasę, która ma wiele konstruktorów?
- 23. Jak utworzyć strukturę, która zawiera własną listę?
- 24. Jak używać, kiedy należy przesłać dalej plik w funkcji, która jest również odroczoną obietnicą?
- 25. DDD Alternative, która również rysuje ładne obrazy struktur danych
- 26. Jak utworzyć funkcję, która nic nie zwraca
- 27. Czy jest możliwe aby wywołać funkcję modułu od wewnątrz klasy, która jest również w tym module
- 28. Jak mogę "usunąć" klasę, która została zadeklarowana jako
- 29. Czy "lista koksów wiśniowych" jest "listą koksów"?
- 30. C# Jak prawidłowo testować klasę, która podąża za wzorcem dekoratora?
Podaj ['__getitem__'] (https://docs.python.org/2/reference/datamodel.html#object.__getitem__) – NightShadeQueen