Seite 1 von 1
Speichern einer Klasse
Verfasst: Montag 28. Januar 2013, 13:20
von Pythoraner123
Hallo,
ich bin dabei ein rollenspiel zu programmieren.
Nun will ich die ganzen Dateien (level, name usw) mit dem modul pickle abspeichern.
Dies funktioniert nicht und ich bekomme folgende Fehlermeldung
Code: Alles auswählen
Traceback (most recent call last):
File "C:\Python32\Programme\Rollenspiel.py", line 163, in <module>
charakter_daten_liste=pickle.load(datei)
TypeError: 'str' does not support the buffer interface
Wie schaffe ich es das zu vermeiden?
Danke schon mal im Voraus
Re: Speichern einer Klasse
Verfasst: Montag 28. Januar 2013, 13:29
von BlackJack
@Pythoraner123: `load()` ist zum laden und nicht zum Speichern.
Ansonsten wäre der relevante Quelltext zur Fehlermeldung und der *komplette* Traceback hilfreich.
Re: Speichern einer Klasse
Verfasst: Montag 28. Januar 2013, 13:43
von Pythoraner123
Ne das Problem trat beim laden auf
Für das Speichern hab ich eine Funktion verwendet
Code: Alles auswählen
def speichern(charakter):
datei=open("gespeicherte_charakterdaten.pkl", "w")
charakakter_daten_liste=[charakter.name, charakter.leben, charakter.angriffskraft, charakter.level, charakter.erfahrung, charakter.erforderliche_xp, charakter.gold]
datei.close()
Laden im Hauptprogramm:
Code: Alles auswählen
datei=open("gespeicherte_charakterdaten.pkl", "r")
charakter_daten_liste=pickle.load(datei)
c1=Charakter("Name")#Mehr als den Namen braucht man nicht
c1.laden(charakter_daten_liste, datei)
Fehlermeldung(war komplett):
Code: Alles auswählen
Traceback (most recent call last):
File "C:\Python32\Programme\Rollenspiel.py", line 163, in <module>
charakter_daten_liste=pickle.load(datei)
TypeError: 'str' does not support the buffer interface
Re: Speichern einer Klasse
Verfasst: Montag 28. Januar 2013, 14:06
von Tris
Du musst binär speichern/öffnen mit pickle.
Sprich, aus
datei=open("gespeicherte_charakterdaten.pkl", "w")
wird
datei=open("gespeicherte_charakterdaten.pkl", "wb")
Re: Speichern einer Klasse
Verfasst: Montag 28. Januar 2013, 14:11
von Sirius3
Hallo Pythoraner123,
wo schreibst Du in
Code: Alles auswählen
def speichern(charakter):
datei=open("gespeicherte_charakterdaten.pkl", "w")
charakakter_daten_liste=[charakter.name, charakter.leben, charakter.angriffskraft, charakter.level, charakter.erfahrung, charakter.erforderliche_xp, charakter.gold]
datei.close()
irgendwas in die Datei?
Du öffnest und schließt sie nur. Sollte Dir auch an der Dateigröße (0) auffallen.
Bei pickle kann man ganze Objekte speichern und muß sich nicht extra Lade- und Schreib-Routinen selbst bauen:
Code: Alles auswählen
with open("gespeicherte_charakterdaten.pkl", "wb") as datei:
pickle.dump(charakter, datei)
Code: Alles auswählen
with open("gespeicherte_charakterdaten.pkl", "rb") as datei:
charakter=pickle.load(datei)
Grüße
Sirius
Re: Speichern einer Klasse
Verfasst: Montag 28. Januar 2013, 14:26
von Pythoraner123
So es klappt jetzt...
Danke für die Hilfe.
Re: Speichern einer Klasse
Verfasst: Montag 28. Januar 2013, 14:40
von BlackJack
An der Stelle vielleicht noch der Hinweis, dass man nichts in Pickle-Dateien sichern sollte, was man potentiell lange aufheben will und nicht 100%ig sicher ist, dass sich die gespeicherten Datentypen nicht mehr verändern. Es werden nur die Daten selbst gespeichert und die Namen der Datentypen, dass heisst wenn man an denen inhaltlich zu viel ändert, oder sie einfach nur umbenennt oder die Paketstruktur umorganisiert, kann es passieren, dass man die Daten nicht mehr laden kann.
Re: Speichern einer Klasse
Verfasst: Montag 28. Januar 2013, 16:02
von mutetella
Tris hat geschrieben:Du musst binär speichern/öffnen mit pickle.
Kommt darauf an, welches Protocol man verwendet bzw. welchen protocol-Parameter man übergibt.
Aber es stimmt natürlich, dass man mit 'wb'/'rb' auf der sicheren Seite ist.
mutetella
Re: Speichern einer Klasse
Verfasst: Montag 28. Januar 2013, 16:20
von Leonidas
mutetella hat geschrieben:Tris hat geschrieben:Du musst binär speichern/öffnen mit pickle.
Kommt darauf an, welches Protocol man verwendet bzw. welchen protocol-Parameter man übergibt.
Alle davon sind binär auch wenn es nicht immer danach aussieht.
Re: Speichern einer Klasse
Verfasst: Montag 28. Januar 2013, 17:12
von mutetella
@Leonidas
Weshalb kann ich dann via protocol 0 gepickelte Daten im 'non-binären' Modus speichern und lesen?
mutetella
Re: Speichern einer Klasse
Verfasst: Montag 28. Januar 2013, 18:06
von /me
Re: Speichern einer Klasse
Verfasst: Montag 28. Januar 2013, 18:07
von snafu
Zum Abspeichern von Spielständen und dergleichen würde ich ja eher XML oder (bevor ich erschlagen werde) JSON verwenden. Pickle ist IMHO nur zum temporären Zwischenspeichern wirklich geeignet. Anwendungsfälle wären zum Beispiel die Kommunikation zwischen zwei verschiedenen Python-Interpreter Prozessen oder in bestimmten Situationen zwecks Caching. In deinem Fall solltest du aber wie gesagt besser ein eigenes Datenformat erstellen. Denkbar wären zweistufige Dictionaries ("Kategorien" auf der obersten Ebene und Eigenschaften mit Werten jeweils als Inhalt der Untergruppe), welche im schon oben genannten JSON-Format abgespeichert werden. Das ist auf Dauer einfach robuster.
Hier mal ein Beispiel, wie so eine JSON-Datei aussehen kann:
http://de.wikipedia.org/wiki/JSON#Beispiel
Re: Speichern einer Klasse
Verfasst: Montag 28. Januar 2013, 18:11
von BlackJack
@mutetella: Wenn Du das konsequent und auf dem selben Betriebssystem falsch machst, dann begehst Du den gleichen Fehler beim Schreiben und beim Lesen. Das funktioniert mit *jedem* Pickle-Protokoll. Was mit *keinem* funktioniert, auch nicht mit 0, ist das Mischen von 'b' und nicht 'b' beim Lesen/Schreiben, und das Lesen von Pickles die unter Windows ohne 'b' gespeichert wurden unter einem anderen System — egal ob mit oder ohne 'b'.
@/me: Mein letzter Satz eben widerspricht anscheinend der Dokumentation, aber das ist die Erfahrung die ich mit Pickles gemacht habe.
Re: Speichern einer Klasse
Verfasst: Montag 28. Januar 2013, 18:52
von /me
BlackJack hat geschrieben:@/me: Mein letzter Satz eben widerspricht anscheinend der Dokumentation, aber das ist die Erfahrung die ich mit Pickles gemacht habe.
Der Punkt ist, dass man sich das picklen im Textmodus gar nicht erst angewöhnen sollte. Es geht halt nur mit dem Protokoll-Level 0 und sonst nicht. Der Binärmodus hingegen funktioniert immer.
Auf das grundsätzliche Pickle-Problem bin ich schon sehr früh gestoßen. Ich hatte eine komplexe XML-Datei die transformiert und in diverse aus eigenen Klassen aufgebaute Python-Datenstrukturen übernommen wurde. Das passierte bei jedem Programmstart. Zur Performancesteigerung war dann das picklen der Daten und ein gepickletes Einlesen gut geeignet. Dann kam der Tag als ich die Klassen umbaute und mir das ganze Zeug beim Einlesen um die Ohren flog. Selten war ich so glücklich über eine Versionskontrollsystem ...
Re: Speichern einer Klasse
Verfasst: Dienstag 29. Januar 2013, 01:41
von vegaseat
Ach du lieber Himmel!
Du kannst nur die Klasseninstanz pickeln. Die genaue Klasse muss in deinem Program vorhanden sein.
Re: Speichern einer Klasse
Verfasst: Dienstag 29. Januar 2013, 09:46
von mutetella
/me hat geschrieben:Be sure to always open pickle files created with protocols >= 1 in binary mode. For the old ASCII-based pickle protocol 0 you can use either text mode or binary mode as long as you stay consistent.
Als ich die Dokumentation gelesen habe, stand das dort noch nicht... ich schwör's...!
mutetella
Re: Speichern einer Klasse
Verfasst: Dienstag 29. Januar 2013, 11:53
von /me
mutetella hat geschrieben:Als ich die Dokumentation gelesen habe, stand das dort noch nicht... ich schwör's...!
Du kennst doch den alten Journalisten-Spruch: "Aber schreib das erst in Wikipedia damit es auch stimmt.".

Re: Speichern einer Klasse
Verfasst: Mittwoch 30. Januar 2013, 19:01
von Hyperion
vegaseat hat geschrieben:
Du kannst nur die Klasseninstanz pickeln.
Du meinst ein "Exemplar"
vegaseat hat geschrieben:
Die genaue Klasse muss in deinem Program vorhanden sein.
Und die "ungenaue" muss wo stehen?
