OOP Anfängerfrage
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Du kannst es drehen und wenden wie Du willst: ``gebe_naechsten_Datensatz`` ist und bleibt keine schöne API! Jeder Container in Python ist nach dem Iterator-Protokoll implementiert (bzw. dem älteren, aber kompatiblen __getitem__) und der Benutzer erwartet das einfach. Wieso Du auf Teufel komm raus einen Sonderweg gehen willst, erschließt sich mir nicht...
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
-
BlackJack
@tom1968: Ich sprach nicht davon die *Ausgabe* in der Tabellen-Klasse zu machen, sondern die Schleife. Wobei noch nicht einmal das, denn das Iterieren gehört da auch nicht hinein, sondern in einen eigenen Datentyp. Als API für einen nur vorwärts laufenden Iterator bietet Python ja bereits ein Protokoll welches von vielen Objekten implementiert wird.
Du möchtest aber anscheinend einen Zugriff der vor und zurück gehen kann. Da braucht man dann einen eigenen Typ. Denn die Information gehört IMHO nicht in die Tabelle. „Der aktuelle Datensatz” ist ja eher ein Konzept der Benutzeroberfläche und nicht der Datenhaltung in der Tabelle. Da würde es bei der Tabelle grundsätzlich erst einmal ausreichen den Indexzugriff mit `__getitem__()` möglich zu machen. Damit funktioniert dann zum einen die ``for``-Schleife über die Zeilen der Tabelle automatisch — also das was Python-Programmierer von so einem Datentyp erwarten. Und man kann sich einfach einen Iteratortyp schreiben, der auf der Tabelle operiert. Beziehungweise ganz generell auf Sequenztypen. Ungetestet:
Das könnte man aber auch in den Bereich der Benutzeroberfläche integrieren. Und ich würde dem Ding wohl noch die Methoden für einen normalen Iterator in Python spendieren, also eine entsprechende `__iter__()` und `next()`-Methode.
Wie geht Deine API eigentlich mit den Grenzen um?
Das vor der ``while``-Schleife etwas steht was in der Schleife noch mal vorkommen muss, nämlich den aktuellen Datensatz ausgeben, ist unschön. Das würde man nur einmal schreiben und zwar gleich am Anfang der Schleife.
Beim GUI-Beispiel fällt auf, dass es nicht objektorientiert ist. Das ist bei GUI-Anwendungen IMHO zwingend. Wenn man das nicht in Klassen strukturiert endet man mit einem verworrenen ineinander durch Abhängigkeiten verstrickten Klumpen, den man ab einer gewissen Grösse schlicht nicht mehr versteht.
Beim `command`-Argument fehlt noch ein ``lambda`` um den *Aufruf* der dort steht in eine *Funktion* zu verpacken, die dort erwartet wird.
Man würde die '>'-Schaltfläche auch eher mit einer `naechster_datensatz()`-Methode verbinden, die ihrerseits die Methode zur aktualisierung der Anzeige aufruft, falls das nötig ist.
Du möchtest aber anscheinend einen Zugriff der vor und zurück gehen kann. Da braucht man dann einen eigenen Typ. Denn die Information gehört IMHO nicht in die Tabelle. „Der aktuelle Datensatz” ist ja eher ein Konzept der Benutzeroberfläche und nicht der Datenhaltung in der Tabelle. Da würde es bei der Tabelle grundsätzlich erst einmal ausreichen den Indexzugriff mit `__getitem__()` möglich zu machen. Damit funktioniert dann zum einen die ``for``-Schleife über die Zeilen der Tabelle automatisch — also das was Python-Programmierer von so einem Datentyp erwarten. Und man kann sich einfach einen Iteratortyp schreiben, der auf der Tabelle operiert. Beziehungweise ganz generell auf Sequenztypen. Ungetestet:
Code: Alles auswählen
class Iterator(object):
def __init__(self, sequence):
self.sequence = sequence
self.index = 0
@property
def current_item(self):
return self.sequence[self.index]
def move_forward(self, amount=1):
self.index += amount
if not (0 <= self.index < len(self.sequence)):
self.index = 0 if amount < 0 else len(self.table) - 1
raise IndexError()
def move_backward(self, amount=1):
self.move_forward(-amount)Wie geht Deine API eigentlich mit den Grenzen um?
Das vor der ``while``-Schleife etwas steht was in der Schleife noch mal vorkommen muss, nämlich den aktuellen Datensatz ausgeben, ist unschön. Das würde man nur einmal schreiben und zwar gleich am Anfang der Schleife.
Beim GUI-Beispiel fällt auf, dass es nicht objektorientiert ist. Das ist bei GUI-Anwendungen IMHO zwingend. Wenn man das nicht in Klassen strukturiert endet man mit einem verworrenen ineinander durch Abhängigkeiten verstrickten Klumpen, den man ab einer gewissen Grösse schlicht nicht mehr versteht.
Beim `command`-Argument fehlt noch ein ``lambda`` um den *Aufruf* der dort steht in eine *Funktion* zu verpacken, die dort erwartet wird.
Man würde die '>'-Schaltfläche auch eher mit einer `naechster_datensatz()`-Methode verbinden, die ihrerseits die Methode zur aktualisierung der Anzeige aufruft, falls das nötig ist.
Der momentane Stand ist der dass wenn Grenzen erreicht sind einfach der letzte Datensatz immer wieder zurückgegeben wird.Wie geht Deine API eigentlich mit den Grenzen um?
z.B.
Angezeigt wird Datensatz 2 (index)
>>> tabelle.gebe_vorherigen_Datensatz()
zurückgegeben wird Datensatz 1
>>> tabelle.gebe_vorherigen_Datensatz()
zurückgegeben wird Datensatz 0
>>> tabelle.gebe_vorherigen_Datensatz()
zurückgegeben wird Datensatz 0
Man könnte das natürlich auch ändern so dass nach dem letzten Datensatz wieder der erste zurückgegeben wird, mal sehen.
Momentan habe ich für "Sprünge" von einem Ende zum anderen die Methoden "gebe_ersten_datensatz" und "gebe_letzten_Datensatz"
Was die while Schleife angeht hast du natürlich recht, aber wie gesagt das wurde nur schnell hingeschrieben um die Klasse zu testen.
MfG
Thomas
Ich würde die Daten wahrscheinlich in eine Deque stecken und dann .rotate() benutzen, um die Datensätze zu durchlaufen. Aber das ist wahrscheinlich zu einfach. ^^
EDIT: Wobei ich das bei näherem Überlegen wohl doch nicht tun würde. Ich denke, ein Datentyp, der intern eine Liste benutzt und sich die aktuelle Position merkt, ist letztlich doch die richtige Wahl. Eine Deque würde ja über die ursprünglichen Grenzen hinaus gehen, sobald sie rotiert wurde.
EDIT: Wobei ich das bei näherem Überlegen wohl doch nicht tun würde. Ich denke, ein Datentyp, der intern eine Liste benutzt und sich die aktuelle Position merkt, ist letztlich doch die richtige Wahl. Eine Deque würde ja über die ursprünglichen Grenzen hinaus gehen, sobald sie rotiert wurde.
