Ich möchte eine Klasse in Python mit verschiedenen Attributen und Methoden erstellen, aber um die Funktionalität einer Liste zu erben, so dass ich Objekte an das Objekt selbst und nicht an seine Attribute anhängen kann. Ich möchte "graph[3]
" anstatt "graph.node_list[3]
" sagen können. Gibt es eine Möglichkeit, dies zu tun?Wie mache ich eine Klasse, die auch eine Liste ist?
Antwort
Alles, was Sie wirklich tun müssen, ist eine
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
Nachtrag __getitem__
bieten: Es gibt andere Methoden, die Sie wahrscheinlich auch zur Verfügung stellen möchten. __len__
ist definitiv einer von ihnen. Es gibt eine ziemlich lange Liste von magischen Methoden, ich würde empfehlen, sie durchzugehen und diejenigen auszuwählen, die Sinn ergeben.
Man kann auch von' abc.Sequence' ableiten, um Typüberprüfungen zu besänftigen. Oder implementieren Sie zumindest '__len__' ... – refi64
@ kirbyfan64sos, Dank der virtuellen Unterklassen müssen Sie nicht von irgendwelchen' collections' 'abc's erben, außer Sie wollen ihre Methoden erben. – Navith
@Navith Ich bezog mich auf Typüberprüfer wie Mypy. :) – refi64
Sie wollen einige spezielle Methoden, wie __getitem__
im Fall von Listen hinzuzufügen. Schauen Sie sich auf:
https://docs.python.org/2/reference/datamodel.html#emulating-container-types
Sie können nur erben von list
:
class Foo(list):
def __init__(self):
pass
Aber Subklassen builtin Typen nicht unbedingt eine gute Idee ist.
collections.abc.Sequence
(oder seit 3.5, typing.Sequence[T]
) ist die Art, wie ich es tun würde.
Da Python duck typing verwendet, der Hauptunterschied zwischen einer Liste aus, und jedem anderen Objekt ist der Satz von Methoden es aussetzt. Sie können die primären Attribute (Methoden und Felder) eines Objekts mit der Funktion dir()
leicht sehen.
>>> [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']
Offensichtlich gibt es viele Methoden, die hier, und Sie wahrscheinlich kümmern sich nicht um die meisten von ihnen. Wenn Sie jedoch das Verhalten einer Liste wirklich replizieren möchten, möchten Sie sie wahrscheinlich implementieren. Die meisten der __...__
Methoden sind in Pythons definiert, wenn Sie sie nachschlagen möchten.
Von dieser Seite:
Mutable Sequenzen Methoden bieten sollten
append()
,count()
,index()
,extend()
,insert()
,pop()
,remove()
,reverse()
undsort()
, wie Python-Standardlistenobjekte. Schließlich sollten die Sequenztypen Addition (dh Verkettung) und Multiplikation (dh Wiederholung) implementieren, indem sie die unten beschriebenen Methoden definieren:__add__()
,__radd__()
,__iadd__()
,__mul__()
,__rmul__()
und__imul__()
; Sie sollten keine anderen numerischen Operatoren definieren. Es wird empfohlen, dass beide Zuordnungen und Sequenzen die__contains__()
-Methode implementieren, um eine effiziente Verwendung des in-Operators zu ermöglichen; Für Mappings sollte In die Schlüssel des Mappings durchsuchen. Für Sequenzen sollte es die Werte durchsuchen. Es wird außerdem empfohlen, dass beide Zuordnungen und Sequenzen die__iter__()
-Methode implementieren, um eine effiziente Iteration durch den Container zu ermöglichen. Für Zuordnungen sollte__iter__()
dasselbe wie keys() sein; Für Sequenzen sollte es die Werte durchlaufen.
Die Funktion, über die Sie insbesondere nach Indexnachfragen fragen, wird von __getitem__
bereitgestellt. Ich würde vorschlagen, auch __contains__()
und __iter__()
(und vielleicht __len__()
) zu implementieren, zumindest.
- 1. Wie mache ich eine Liste mit Zeichen, die Objekten entsprechen?
- 2. Wie mache ich die Autocomplete-Liste für eine TextBox editierbar?
- 3. Wie konvertiere ich Varargs in eine einzelne Liste, auch wenn der Parameter bereits eine Liste ist?
- 4. Wie mache ich eine Zeitsequenz?
- 5. Wie mache ich eine Knopfanimation?
- 6. Wie mache ich eine Java-Klasse in Clojure unveränderlich?
- 7. Wie mache ich eine Liste außerhalb von if zugänglich?
- 8. Wie mache ich eine JSON-Repräsentation einer Java-Klasse?
- 9. Wie mache ich eine Liste von assoziativen Array in Yaml
- 10. Wie mache ich eine Klasse Vorrang vor einer ID?
- 11. Wie mache ich eine faule Liste in einer eifrigen Sprache?
- 12. Wie mache ich pymongos find() eine Liste zurück?
- 13. Wie mache ich eine Bootstrap-Drop-Down-Liste?
- 14. Wie mache ich eine Arraylist public
- 15. Ist das eine schlechte Javascript-Praxis, die ich hier mache?
- 16. Wie kann ich eine Klasse Observable erweitern, wenn sie auch eine andere Klasse erweitert hat?
- 17. Wie mache ich eine Instanz bewegen
- 18. Wie mache ich eine saubere asynchrone Schleife?
- 19. Optaplanner: Planungsvariable, die auch eine Schattenvariable ist?
- 20. Wie mache ich einen Destruktor für die Klasse in eine andere Klasse mit Zeigern C++? So etwas wie One-Direction-Liste Container-Klasse und Klasse von Knoten
- 21. Wie mache ich eine Variable local
- 22. Wie mache ich eine einfache Zeitreihe?
- 23. Wie mache ich eine Klasseneigenschaft mit mox?
- 24. Wie mache ich eine Methode, die ein generisches Klassenobjekt erzeugt?
- 25. Wie mache ich eine Teilübereinstimmung in Elasticsearch?
- 26. Wie mache ich eine Kompilierung compileSdkVersion?
- 27. Wie mache ich eine wirklich transparente Kontrolle?
- 28. Wie mache ich eine GUI, die sich so verhält?
- 29. Wie kann ich eine Klasse deklarieren, die typedef'd ist?
- 30. Wie mache ich eine Säuberung nach SIGKILL?
Stellen Sie ein ['__getitem__'] bereit (https://docs.python.org/2/reference/datamodel.html#object.__getitem__) – NightShadeQueen