danke Blackjack,
also instanziere ich Players über den return-Wert der Klassenmethode?! Macht man das generell so bei Klassen, wo man Daten einlädt?
Und in die JSON Datei fliesst ein Dict mit einem Key "players" und als Value eine Liste mit den Player-Objekten, die in to_dict() in JSON-Strings umgewandelt werden?! Hab ich das richtig verstanden?
Generelles Vorgehen beim Programmieren
Man macht das, weil man es ermoeglichen will, ein Players-Objekt auch so zu konstruieren. Ohne das da gleich ein dicker Lade-Mechanismus anspringt, fuer den man eine Menge an Randbedingungen erfuellen muss. So koennte man zB spaeter auch eine SQLite DB benutzen, oder die Klasse fuer Tests ohne alles instantiieren.
Und ich denke mal du hast das richtig verstanden. Denn so steht's ja auch in BJs code.
Und ich denke mal du hast das richtig verstanden. Denn so steht's ja auch in BJs code.
nein, von außen sieht es so aus, als ob Du eine Instanz der Klasse erzeugst, indem Du eine Klassenmethode aufrufst. Klassenmethoden helfen, wenn man verschiedene Arten hat, wie man Instanzen erzeugen könnte.
Das Umwandeln in einen String findet erst bei `json.dump` statt.
Das Umwandeln in einen String findet erst bei `json.dump` statt.
-
- User
- Beiträge: 22
- Registriert: Dienstag 13. August 2019, 14:38
Dann wird die "JSON-kompatible" Struktur in to_dict() erstellt? Wenn ja, wie muss das aussehen?__blackjack__ hat geschrieben: ↑Freitag 16. August 2019, 12:39 @schnickalot: Da muss man schon etwas mehr machen, denn das funktioniert ja nur wenn man ausschliesslich Werte hat, deren Typ vom JSON-Modul standardmässig in JSON-Werte umwandeln kann und nicht mit beliebigen Datentypen. Das JSON-Modul wüsste nicht was es beim Speichern mit einem `Player`-Objekt machen sollte. Und beim laden werden aus JSON-Daten auch nicht einfach so `Player`-Objekte. Da braucht man in beide Richtungen jeweils mindestens einen Zwischenschritt der Python-Objekte in eine ”JSON-kompatible” Struktur überführt die man dann speichern kann, und die JSON-Datenstruktur die man geladen hat, wieder in Python-Objekte.
-
- User
- Beiträge: 22
- Registriert: Dienstag 13. August 2019, 14:38
ok danke.. also muss jedes Attribut, welches Daten hat, die ich speichern möchte, in ein erneutes dict geschrieben werden?
Mal ganz billig so?:
So sieht meine Player-Klasse aus:
Mal ganz billig so?:
Code: Alles auswählen
def to_dict(self):
dict = {}
dict["first_name"] = self.first_name
dict["last_name"] = self.last_name
dict["team"] = self.team.name
dict["games_won"] = self.games_won
dict["games_lost"] = self.games_lost
dict["frames_won"] = self.frames_won
dict["frames_lost"] = self.frames_lost
return dict
So sieht meine Player-Klasse aus:
Code: Alles auswählen
class Player:
def __init__(self, first_name, last_name, team):
self.first_name = first_name
self.last_name = last_name
self.team = team
self.score = 0
self.games_won = 0
self.games_lost = 0
self.frames_won = 0
self.frames_lost = 0
@property
def full_name(self):
return "{} {}".format(self.first_name, self.last_name)
@property
def games_total(self):
return self.games_won + self.games_lost
@property
def frames_total(self):
return self.frames_won + self.frames_lost
dict solltest du das nicht nennen, denn so heisst der Typ. Und ein bisschen umstaendlich machst du das auch. Einfacher:
ACHTUNG: ich BENUTZE dict, den Typ, als Konstruktor. Einen Namen hat das Ding nicht.
Code: Alles auswählen
def to_dict(self):
return dict(
first_name=self.first_name,
frames_lost=self.frames_lost,
...
)
-
- User
- Beiträge: 22
- Registriert: Dienstag 13. August 2019, 14:38
ok prima. Vielen Dank.
zu from_dict():
Dann return ich dort cls(first_name, last_name, team, games_won=games_won, games_lost=games_lost... und weitere named args, die ich dann auch in der __init__ übergeben muss:
class Player:
def __init__(self, first_name, last_name, team, **kwargs)
richtig?
zu from_dict():
Dann return ich dort cls(first_name, last_name, team, games_won=games_won, games_lost=games_lost... und weitere named args, die ich dann auch in der __init__ übergeben muss:
class Player:
def __init__(self, first_name, last_name, team, **kwargs)
richtig?
-
- User
- Beiträge: 22
- Registriert: Dienstag 13. August 2019, 14:38
hatte ich schon so da stehen, dachte aber ist professioneller mit **kwargs.
Danke euch allen. Hab's langsam kapiert
Danke euch allen. Hab's langsam kapiert
-
- User
- Beiträge: 22
- Registriert: Dienstag 13. August 2019, 14:38
sorry muss noch mal fragen.. wie genau muss die from_dict() aussehen? Könnt Ihr mir den code mal bitte vorschreiben? Ich steh völlig auf dem Schlauch..
Du bekommst ein Wörterbuch und übergibst die Werte an die Klasse. Im einfachsten Fall so:
Du hast aber nicht den einfachsten Fall, denn die Auflösung von Teamname nach Team muß auch noch in `from_dict` stattfinden:
Code: Alles auswählen
class Player:
def __init__(self, first_name, last_name, team, games_won=0, games_lost=0, ...):
....
@classmethod
def from_dict(cls, entry):
return cls(**entry)
Code: Alles auswählen
@classmethod
def from_dict(cls, entry, teams):
entry = dict(entry)
team_name = entry.pop('team_name')
return cls(team=teams[team_name], **entry)
-
- User
- Beiträge: 22
- Registriert: Dienstag 13. August 2019, 14:38
danke.. ich glaub ich versteh nicht wie genau das dict aussieht, weches ich speichere und lade. So wie ich es verstehe habe ich ein Dict mit nur einem Key "players" und als wert wiederum ein Dict, mit den keys first_name. last_name etc und den dazugehörigen Werten.
Visuell mal so dargestellt:
Woran ich die ganze Zeit knabber.. so könnte man ja nur einen Player speichern, weil ja in einem Dict nicht 2x der gleiche Key vorhanden sein darf. Also kann es ja keinen 2. Key first_name, last_name etc geben, um die Daten weiterer Spieler zu speichern.
Wo ist denn mein Denkfehler?
Visuell mal so dargestellt:
Code: Alles auswählen
"players": "first_name": "Peter",
"last_name": "Schmidt"
"team": "BC Buxtehude"
usw.
Wo ist denn mein Denkfehler?
-
- User
- Beiträge: 22
- Registriert: Dienstag 13. August 2019, 14:38
meinst du das?
data = {
"players": [player.to_dict() for player in self._players.values()]
}
wie sehen denn die Inhalte der ListComprehensive aus? Wahrscheinlich nicht so wie ich es oben dargestellt habe?!
data = {
"players": [player.to_dict() for player in self._players.values()]
}
wie sehen denn die Inhalte der ListComprehensive aus? Wahrscheinlich nicht so wie ich es oben dargestellt habe?!
- __blackjack__
- User
- Beiträge: 13080
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Ich hatte die Player-JSON-Objekte in ein JSON-Array gesteckt, weil der Name sonst ja redundant gespeichert würde.
Wie ein einzelner Player da aussieht bestimmt die `to_dict()`-Methode von `Player`, denn die wird ja für jedes Element in der „list comprehension“ (LC) aufgerufen.
Ansonsten kann man ja auch einfach mal in die gespeicherte JSON-Datei rein schauen wenn man sich das nicht vorstellen kann.
Wie ein einzelner Player da aussieht bestimmt die `to_dict()`-Methode von `Player`, denn die wird ja für jedes Element in der „list comprehension“ (LC) aufgerufen.
Ansonsten kann man ja auch einfach mal in die gespeicherte JSON-Datei rein schauen wenn man sich das nicht vorstellen kann.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
-
- User
- Beiträge: 22
- Registriert: Dienstag 13. August 2019, 14:38
Ja das ist richtig mir fehlt die Praxis.. bin nur gerade dabei meinen fertigen Anfänger code umzuschreiben. Schwer da was laufbares zu haben. Wollte erstmal die Klassen sauber haben bevor ich die GUI Klassen 3x ändern muss. Ich bau mir heut Abend mal ne Testumgebung auf und schau mir es mal in Detail am. Danke erstmal für die Infos
-
- User
- Beiträge: 22
- Registriert: Dienstag 13. August 2019, 14:38
nur mal kurz Rückmeldung.. wenn man sieht was rauskommt, ist dann doch alles klarer. Danke nochmal an alle!