warum pickled es so komisch?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
jo_hb
User
Beiträge: 72
Registriert: Donnerstag 26. April 2007, 09:21

hallo,
diesmal eine ganz konkrete und ausführliche Frage: :)

Ich programmiere grade an einer datenbank für Pferderennen, habe mir dafür ein paar geeignete Klassen geschrieben (rennen, rennstrecke, pferd, wetten, etc.) - die oberste 'ebene' ist dabei quasi 'rennen', und dann habe ich eine liste mit diesen rennen, also [rennen1, rennen2, rennen3, ...]

Jetzt möchte ich das ganze natürlich speichern und laden können - hatte dazu im ersten Anlauf selber export und import für ein semicolon-separiertes textfile geschrieben, aber weil meine komplette Datenstruktur schon recht umfangreich ist gibt diese Methode erstens ellenlangen code und ist zweitens umständlich, wenn es mal was zu ändern gibt (weil ich dann immer schauen muss dass dieselben daten an derselben stelle gelesen werden wie sie geschrieben werden und so weiter...)

Also dachte ich an pickle. Habe um das auszuprobieren mal auf die schnelle folgenden Beispielcode geschrieben:

Code: Alles auswählen

import pickle
import random

class runner:
    def __init__(self, name, number):
        self.name = name
        self.number = number
    def __str__(self):
        return '(' + self.name + ' - ' + str(self.number) + ')'

class race:
    def __init__(self, track, date):
        self.track = track
        self.date = date
        self.runners = []
    def addRunner(self, name, number):
        print name, number
        a = runner(name, number)
        self.runners.append(a)
    def __str__(self):
        a = self.track + ' - ' + self.date + ' - '
        b = ''
        for i in self.runners:
            b = b + str(i)
        return a + b

def randomname(index):
    m = random.randint(10,20)
    r = ''
    for i in range(0,m):
        r = r + chr(random.randint(65,90))
    r = str(index) + r
    return r
    
    
myrace = race('testtrack', '02.dec2006')
for i in range (0,100):
    n = randomname(i)
    myrace.addRunner(n, i)

output = open('c:\pickle.pkl', 'wb')
pickle.dump(myrace, output, -1)
output.close

input_file = open('c:\pickle.pkl', 'rb')
mypickledrace = pickle.load(input_file)

print mypickledrace
Aber leider, wenn ich dieses programm ein paarmal nacheinander laufen lasse, funktioniert es nur jedes xte mal richtig und produziert ansonsten anscheinend völlig beliebige Fehler, zB die folgenden, die allesamt beim wiedereinlesen des pickle-files auftreten:

AttributeError: 'str' object has no attribute '__dict__'
KeyError: '\x00'
KeyError: '\x0f'
TypeError: 'str' object does not support item assignment
EOFError
ValueError: insecure string pickle

Das ist zwar wie gesagt nur ein Beispiel, die eigentlich zu pickelnde datenstruktur ist um einiges komplexer (enthaltene Typen sollen dann bool, int, float, str, datetime sein), aber wenn's noch nicht mal mit diesen simplen klassen klappt... Naja, die Frage ist: Wieso klappt es nicht? Wieso gibt es so viele verschiedene Fehler? Was mache ich falsch?

Haben die verschiedenen Fehler damit zu tun dass ich random benutze? Aber 65-90 ergibt doch eigentlich nur stinknormale grossbuchstaben, oder? Oder hat es eher damit zu tun dass die strings in runner.name unterschiedlich lang sind? (das allerdings wäre in meiner eigentlichen Anwendung natürlich auch der fall...)

Ich hatte mir grad auch schon SQLite angeguckt, aber irgendwie kommt es mit vor als würde eigentlich pickle für meine Anwendung schon reichen, schliesslich will ich nix weiter als die ganze Struktur an einem Stück auf die Platte schreiben und hinterher komplett wieder lesen bzw. wiederherstellen.

Besten Dank schonmal,
gruss,
jo
Gromit
User
Beiträge: 51
Registriert: Montag 8. Mai 2006, 19:07

Es muss in Zeile 44

Code: Alles auswählen

output.close()
und nicht

Code: Alles auswählen

output.close
heissen.

HTH,
Gerald
jo_hb
User
Beiträge: 72
Registriert: Donnerstag 26. April 2007, 09:21

Hm, stimmt... und daran lag es sogar, so ein blöder Fehler! Vielen Dank! :)
Antworten