Hallo.
Ich schreibe gerade eine Klasse, die eigentlich nur als Behälter (Liste) für mehrere Objekte einer anderen Klasse dient und nur ein paar funktionen, wie zum Beispiel das hinzufügen/löschen und Sortieren braucht.
Also konkret handelt es sich um eine Liste, in der sich alle Spielkarten (die die Instanz der Spielkarten-Klasse sind) befinden.
Jetzt weiß ich aber grad nicht, ob die Klasse von `list` erben soll, oder nicht ... Im Prinzip ist es ja nur eine Liste, ich erstelle inerhalb der Klasse auch ein list-Objekt, in das alle Spielkarten reingeschrieben werden. Die anderen Methoden sind wie gesagt zum sortieren usw da, also zum Verwalten der Karten.
Klasse von list erben oder nicht?
Klare AntwortLeonidas hat geschrieben:Wenn es sich wie eine Liste verhalten soll, dann würde ich auch von einer Liste erben.
Aber dann stellt sich mir das Problem: Ich hab im Prinzip keine Ahnung von dem Datentyp `list`.
Okay, ich kann mir mit help die Methoden anschauen, aber wie greife ich jetzt inerhalb der Klasse auf die Liste/deren Elemente zu? Also ... Die Klasse an sich ist ja die Liste, aber in welcher Variable und wie und wo sind die Daten gespeichert?
Wenn ich folgendes schreibe:
Code: Alles auswählen
class bla(list):
def __init__(self):
pass
Aber wie greife ich jetzt auf die Elemente zu usw?
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
Würde ich nicht machen, da du die Möglichkeit verlierst über den Konstruktor eine Liste in ``bla`` umzuwandeln.Karl hat geschrieben:Wenn ich folgendes schreibe:Code: Alles auswählen
class bla(list): def __init__(self): pass
``self[index]``Karl hat geschrieben:Aber wie greife ich jetzt auf die Elemente zu usw?
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Wie dann? Den Konstruktor einfach weglassen?Leonidas hat geschrieben: Würde ich nicht machen, da du die Möglichkeit verlierst über den Konstruktor eine Liste in ``bla`` umzuwandeln.
Und eigentlich will ich ja auch nicht jede beliebige Liste in ``bla`` umwandeln, höchstens Listen, die nur Elemente vom typ ``blubb`` haben, da ich nur Elemente vom typ ``blubb`` in der Liste speichern will
Logisch thxLeonidas hat geschrieben:``self[index]``
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
Dann schreib den Konstruktor wenigstens sinnvoll, d.h. die Argumente checken ob sie vom passenden Typ sind und dann den Parent-Konstruktor aufrufen.Karl hat geschrieben:Und eigentlich will ich ja auch nicht jede beliebige Liste in ``bla`` umwandeln, höchstens Listen, die nur Elemente vom typ ``blubb`` haben, da ich nur Elemente vom typ ``blubb`` in der Liste speichern will
Naja, eigentlich ist __init__ so gesehen auch kein Konstruktor, sondern eher ein Initialisierer.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
JoEyDu hat geschrieben:Ja, dazu hat man ja u.A. die Vererbung.Karl hat geschrieben:Wie dann? Den Konstruktor einfach weglassen?
Okay, das klappt doch besser, als ich dachte
Perfekt, danke
Edit: Aber wie kann ich jetzt erreichen, dass in der Liste nur ein Datentyp (der meiner Kartenklasse) zugelassen wird? Ich will ja schön fleißig alle Fehlerquellen vermeiden oder abfangen können
@Karl: Dann nimm eine andere Programmiersprache. So etwas ist in Python unüblich. Somit würdest Du verhindern, dass man Objekte eines anderen Typs in Deine Liste steckt, die sich aber genau so verhalten wie von Karten erwartet wird.
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
Wie BlackJacks sagte ist sowas in Python unüblich. Man würde es in Python 2.x so implementieren, dass man ``__init__`` überschreibt, dort die übergebenen werte testet und mit diesen dann ``list.__init__`` aufruft.Karl hat geschrieben:Edit: Aber wie kann ich jetzt erreichen, dass in der Liste nur ein Datentyp (der meiner Kartenklasse) zugelassen wird? Ich will ja schön fleißig alle Fehlerquellen vermeiden oder abfangen können
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Naja, stimmt schon. Du beziehst dich wohl auf den Spruch mit der Ente und dem Frosch, oder wie das war ;p wenn der Frosch quakt wie eine Ente, ist er eine Ente.BlackJack hat geschrieben:@Karl: Dann nimm eine andere Programmiersprache. So etwas ist in Python unüblich. Somit würdest Du verhindern, dass man Objekte eines anderen Typs in Deine Liste steckt, die sich aber genau so verhalten wie von Karten erwartet wird.
Wenn ich aber jetzt einen Integer reinschmeiße, dann führt das früher oder später, nämlich dann, wenn der Integer sich anders verhält als meine Karten, zu einem Error.
Sowas wie string bla = "blubb" vermisse ich irgendwie schon ab und zu ;o
Es ist halt nunmal Fakt, dass in einen Kartenstapel nur Karten gehören und keine Frösche oder Enten. Spätestens wenn ich den Frosch im Deck habe und wissen will, was für einen Rang er hat, und ob ich jetzt ein Full House hab, stimmt irgendwas nicht mehr ;o
Aber naja ... Wenn du meinst dass es in Python einfach unüblich ist, lass ich's einfach mal so? Und wenn mir wer n Frosch in's Deck schmeißt, selbst schuld oO
(Sorry, dass ich einen neuen Post erstelle, aber ich hab Angst, dass er sonst nicht wahrgenommen wird :p)
Ich habe ja jetzt eine Klasse, die von ``list`` erbt.
Alles schön und gut, aber:
So, jetzt erklär ich mal das Problem:
x ist eine Instanz von Blubb, y ebenso.
a (= x + y) reagierte auf print plötzlich ganz anders, also hab ich mal type(a) gemacht und siehe da ... a ist wieder eine Liste oO
Ich will aber, dass a auch eine Instanz von Blubb ist ;o
Wie mach ich das denn jetzt?
bei __add__ eine neue Instanz erstellen und die mit beiden Listen füllen und dann returnen?
Warum geht das nicht automatisch?
Ich habe ja jetzt eine Klasse, die von ``list`` erbt.
Alles schön und gut, aber:
Code: Alles auswählen
class Blubb(list):
# ...
x = Blubb()
y = Blubb()
x.append(Card(n, m))
y.append(Card(n, m))
#...
a = x + y
print a
x ist eine Instanz von Blubb, y ebenso.
a (= x + y) reagierte auf print plötzlich ganz anders, also hab ich mal type(a) gemacht und siehe da ... a ist wieder eine Liste oO
Ich will aber, dass a auch eine Instanz von Blubb ist ;o
Wie mach ich das denn jetzt?
bei __add__ eine neue Instanz erstellen und die mit beiden Listen füllen und dann returnen?
Warum geht das nicht automatisch?
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
Weil ``x + y`` eigentlich ``x.__add__(y)`` ist und ``__add__`` ist in Blubb nicht implementiert, also geht er über die MRO in die Elternklassen, wo ``list.__add__`` ist, welches logischerweise eine Liste zurückgibt und kein ``Blubb``.Karl hat geschrieben:siehe da ... a ist wieder eine Liste oO
Ich will aber, dass a auch eine Instanz von Blubb ist ;o
Wie mach ich das denn jetzt?
bei __add__ eine neue Instanz erstellen und die mit beiden Listen füllen und dann returnen?
Warum geht das nicht automatisch?
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Ahh, ergibt SinnLeonidas hat geschrieben:Weil ``x + y`` eigentlich ``x.__add__(y)`` ist und ``__add__`` ist in Blubb nicht implementiert, also geht er über die MRO in die Elternklassen, wo ``list.__add__`` ist, welches logischerweise eine Liste zurückgibt und kein ``Blubb``.
Dann mach ich's eben so:
Code: Alles auswählen
def __add__(self, other):
new = Blubb()
for n in xrange(len(self)):
new.append(self[n])
for m in xrange(len(other)):
new.append(other[m])
return new
Naja ich glaub ich hab euch für's erste genug mit Listen gequält
Nur eine Frage noch:
Wenn ich in ``Bla`` 2 Eigenschaften definiere, ``x`` und ``y``, beide sind Integer, dann sortiert ``Blubb.sort()`` die Elemente anscheinend nach diesen Eigenschaften (Die geerbte sort()-Funktion). Aber wie kann dem Teil sagen, dass er nur nach ``x`` oder nur nach ``y`` sortieren soll? Oder muss ich die Funktion dann auch wieder selbst schreiben?
Ja, du kannst auch direkt über die Elemente einer Liste iterieren. Außerdem habe ich mit "chain" noch eine Schleife draus gemacht:Karl hat geschrieben:Oder geht das noch kürzer?
Code: Alles auswählen
import itertools
def __add__(self, other):
new = Blubb()
for e in itertools.chain(self, other)
new.append(e)
return new
"sort" hat eine "key"-Parameter, schau dir das einfach mal in der Doku an. Für kompliziertere Fälle steht auch noch der "cmp"-Parameter zur verfügen, den brauchst du in diesem Fall aber nicht.Karl hat geschrieben:Naja ich glaub ich hab euch für's erste genug mit Listen gequält
Aber wie kann dem Teil sagen, dass er nur nach ``x`` oder nur nach ``y`` sortieren soll? Oder muss ich die Funktion dann auch wieder selbst schreiben?
Ich steh da mit dem Key Parameter völlig auf dem Schlauch.
als Beispiel hab ich nur key=str.lower() gefunden oO das hilft mir ziemlich wenig.
Bei cmp hab ich mal was mit lambda versucht:
Aber das macht ja genau das, was es sonst auch macht. Es soll ja nur einen Wert und nicht beide vergleichen Ich hab keine Ahnung, wie ich das machen soll.
als Beispiel hab ich nur key=str.lower() gefunden oO das hilft mir ziemlich wenig.
Bei cmp hab ich mal was mit lambda versucht:
Code: Alles auswählen
cmp=lambda x,y: cmp(x, y)
Code: Alles auswählen
In [5]: import operator
In [6]: test.sort(key=operator.itemgetter(1))
In [7]: print test
[(9, 91), (8, 92), (7, 93), (6, 94), (5, 95), (4, 96), (3, 97), (2, 98), (1, 99), (0, 100)]
In [8]: test.sort(key=operator.itemgetter(0))
In [9]: print test
[(0, 100), (1, 99), (2, 98), (3, 97), (4, 96), (5, 95), (6, 94), (7, 93), (8, 92), (9, 91)]
Äquivalent dann für Attribute mit operator.attrgetter