Voglio creare una classe in Python con vari attributi e metodi, ma per poter ereditare la funzionalità di una lista, in modo da poter aggiungere oggetti all'oggetto stesso, non a nessuno dei suoi attributi. Voglio poter dire "graph[3]
" anziché "graph.node_list[3]
". C'è un modo per fare questo?Come si crea una classe che è anche una lista?
risposta
Tutto ciò che dovete fare è fornire un Addendum __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
: Ci sono altri metodi probabilmente avrete bisogno di fornire, anche. __len__
è sicuramente uno di questi. C'è una lista piuttosto lunga di metodi magici, io consiglierei di esaminarli e scegliere quelli che hanno senso.
Uno può anche derivare da' abc.Sequence' per placare i controlli di tipo. O almeno implementa '__len__' ... – refi64
@ kirbyfan64sos, Grazie alla sottoclasse virtuale, non è necessario ereditare da nessuno dei' collections' 'abc's, a meno che non si voglia ereditare i loro metodi. – Navith
@Navith Mi riferivo a dama tipo Mypy. :) – refi64
Si desidera aggiungere alcuni metodi speciali, ad esempio __getitem__
in caso di elenchi. Date un'occhiata a:
https://docs.python.org/2/reference/datamodel.html#emulating-container-types
Si può solo ereditare da list
:
class Foo(list):
def __init__(self):
pass
Ma sottoclasse tipi built non è necessariamente una buona idea.
collections.abc.Sequence
(o dal 3.5, typing.Sequence[T]
) è il modo in cui lo farei.
Poiché Python utilizza duck typing, la differenza principale tra un elenco e qualsiasi altro oggetto è l'insieme di metodi che espone. È possibile visualizzare facilmente gli attributi principali (metodi e campi) di un oggetto con la funzione 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']
Ovviamente c'è un sacco di metodi di qui, e probabilmente non si preoccupano più di loro. Ma se il tuo obiettivo era quello di replicare realmente il comportamento di un elenco, probabilmente vorresti implementarlo. La maggior parte dei metodi __...__
sono definiti in Python data model, se si desidera visualizzarli.
Da quella pagina:
sequenze mutabili dovrebbero fornire metodi
append()
,count()
,index()
,extend()
,insert()
,pop()
,remove()
,reverse()
esort()
, come Python oggetti lista standard. Infine, i tipi di sequenza dovrebbero implementare l'aggiunta (che significa concatenazione) e la moltiplicazione (ovvero la ripetizione) definendo i metodi__add__()
,__radd__()
,__iadd__()
,__mul__()
,__rmul__()
e__imul__()
descritti di seguito; non dovrebbero definire altri operatori numerici. Si raccomanda che sia i mapping che le sequenze implementino il metodo__contains__()
per consentire un uso efficiente dell'operatore in; per i mapping, dovrebbe cercare le chiavi del mapping; per le sequenze, dovrebbe cercare tra i valori. Si raccomanda inoltre che sia le mappature che le sequenze implementino il metodo__iter__()
per consentire un'iterazione efficiente attraverso il contenitore; per i mapping,__iter__()
dovrebbe essere uguale a keys(); per le sequenze, dovrebbe scorrere i valori.
La funzione che stai chiedendo in particolare, le ricerche dell'indice, è fornita da __getitem__
. Suggerirei anche di implementare __contains__()
e __iter__()
(e forse __len__()
), come minimo.
- 1. Come si crea una classe in Wollok?
- 2. ToList() - Crea una nuova lista?
- 3. Come si crea una lista <T> da una lista ordinata <int, T>?
- 4. Python crea una lista con itertools.product?
- 5. Rappresenta una classe come dict o lista
- 6. errore che devo implementare una funzione in una classe, anche se è definita la funzione
- 7. E 'possibile chiamare una funzione modulo dall'interno di una classe che è anche in quel modulo
- 8. Come si crea una lingua vincolante?
- 9. In che modo C# crea un'istanza di una classe?
- 10. Come si crea una risorsa PNG?
- 11. Come si crea una diff manuale?
- 12. Come si crea una canalizzazione chiusa?
- 13. Se slicing non crea una copia di una lista né elenca() come posso ottenere una copia reale della mia lista?
- 14. Come si crea una variabile temporanea in una classe di dominio Grails?
- 15. Come si ordina una lista in Jinja2?
- 16. Come si crea una classe generica da una stringa in C#?
- 17. Come si crea una trama verticale numpy?
- 18. Come si crea una pagina 404?
- 19. Crea istanza di una classe generica C#
- 20. Qual è il modo consigliato per verificare che una lista sia una lista di numeri in argomento di una funzione?
- 21. Come si usa hasClass per rilevare se una classe NON è la classe che voglio?
- 22. array numpy che crea con una sequenza
- 23. FakeItEasy crea un falso di una classe
- 24. classe di primo livello che si estende una classe interna
- 25. Restituisce l'elemento di una lista che soddisfa una certa condizione
- 26. Come si crea una finestra popup quando si esegue oauth?
- 27. Come si implementa una macro che crea una stringa tra virgolette per _Pragma?
- 28. Determinare se una classe Java è una classe SE portatile
- 29. Come si crea una lista con un singolo valore in R?
- 30. Crea una classe personalizzata JSON serializzabile
Fornire un ['__getitem__'] (https://docs.python.org/2/reference/datamodel.html#object.__getitem__) – NightShadeQueen