====== Speichern von Objekten ====== Objekte (Zahlen, Strings, numpy-Arrays, Listen, Dictionaries, Objekte, die Instanzen von Klassen sind) lassen sich in Python ganz einfach 'einmachen' (englisch: to pickle) mit Hilfe des Pakets **pickle** (oder in Python 2 des schnelleren, aber äquivalenten Moduls **cPickle**). Dabei wird jeweils ein Objekt in eine Datei geschrieben. Das Objekt darf so groß und komplex sein, wie es will (etwa ein Liste von Listen von Bilddaten). Man kann also im Prinzip alles, was man speichern will, in ein 'dictionary' packen und dieses dann 'picklen'. Diese Sortierarbeit übernimmt das Paket **shelve**, das mit Hilfe von 'pickle' eine einfache Datenbank aufbaut. Das Speichern und laden mit 'pickle' geht so: import pickle # Definiere irgendwelche Objekte objekt =... # Speichern: f = file('dateiname.pickle','wb') p = pickle.Pickler(f) p.dump(o) f.close() # Laden: f = file('dateiname.pickle','rb') p = pickle.Unpickler(f) o = p.load() f.close() Mit dem Paket 'shelve' geht das so: import shelve # Irgendwelche Objekte definieren o1 =... o2 =... o3 =... ### Speichern mit shelve db =shelve.open('dateiname') db['Objekt1'] = o1 db['Objekt2'] = o2 db['Zusatz'] = o3 db.close() ### ... und laden mit shelve db.shelve.open('dateiname') o1geladen = db['Objekt1'] o2geladen = db['Objekt2'] o3geladen = db['Zusatz'] Die Abkürzung 'db' steht für 'database'. **db.keys** ist die Liste der verwendeten Schlüssel, im Beispiel ['Objekt1','Objekt2','Zusatz']. Als Schlüssel kann man außer Strings auch Zahlen verwenden. Damit diese Methoden in Aktion sieht, habe ich ein (albernes) Beispiel angefertigt. Die folgende Datei schreibt nur Daten in den beiden Varianten: #!/usr/bin/env python # -*- coding: utf-8 -*- # # pickle_ex.py # import pickle, shelve class kuchen(object): '''Klasse, die Kuchen-Objekte speichert und bearbeitet''' def __init__(self,sorte,stuecke,zutaten={}): self.sorte = sorte self.stuecke = stuecke self.zutaten = zutaten def __str__(self): '''Anzeige-Format für Objekte der Klasse Kuchen''' ausgabe = \ ("--------------------\n"\ +"Sorte: {0:s}\n"+ "Es sind noch {1:d} Stücke da.\n").format(self.sorte,self.stuecke)\ +"--------------------\n"\ +"Die Zutaten waren:\n" for key in self.zutaten: ausgabe=ausgabe+ "{0:s} ( {1:s} )\n".format(key,self.zutaten[key]) ausgabe=ausgabe+"-------------------\n" return ausgabe def iss(self): '''Methode isst ein Stück''' if self.stuecke>0: self.stuecke-=1 if self.stuecke==0: print "Das war das letzte Stück!" else: print("Es ist leider nichts mehr da") k=kuchen('Kaesekuchen',12,zutaten={'Quark':'500g', 'Zucker':'100g','Mehl':'300g', 'Eier':'4 Stueck'}) e=kuchen('Erdbeerkuchen', 10) print(k) k.iss() k.iss() print(k) print(e) ### Speichern mit pickle f = file('kuchen.pickle','w') p = pickle.Pickler(f) p.dump([k,e]) f.close() ### Speichern mit shelve db=shelve.open('kuchen') db['kuchen1'] = k db['kuchen2'] = e db['kommentar'] = "Es fehlen noch Kuchen für die Feier." db.close() Das nächste Programm liest Daten, bzw. verändert diese im Fall von 'shelve': #!/usr/bin/env python # -*- coding: utf-8 -*- # # unpickle_ex.py # import pickle, shelve class kuchen(object): '''Klasse, die Kuchen-Objekte speichert und bearbeitet''' def __str__(self): '''Anzeige-Format für Objekte der Klasse Kuchen''' ausgabe =\ ("--------------------\n"\ +"Sorte: {0:s}\n"+ "Es sind noch {1:d} Stücke da.\n").format(self.sorte,self.stuecke)\ +"--------------------\n"\ +"Die Zutaten waren:\n" for key in self.zutaten: ausgabe=ausgabe+ "{0:s} ( {1:s} )\n".format(key,self.zutaten[key]) ausgabe=ausgabe+"-------------------\n" return ausgabe def __init__(self,sorte,stuecke,zutaten={}): self.sorte = sorte self.stuecke = stuecke self.zutaten = zutaten def iss(self): '''Methode isst ein Stück''' if self.stuecke>0: self.stuecke- = 1 if self.stuecke == 0: print ("Das war das letzte Stück!") else: print("Es ist leider nichts mehr da") ##### Laden mit pickle print "Pickle ..." f = file('kuchen.pickle','rb') p = pickle.Unpickler(f) l = p.load() print(l) print(l[0]) print(l[1]) print("--------------------") ##### Laden mit shelve print("Shelve ... ") db=shelve.open('kuchen') print(len(db), " Einträge") print(db['kuchen1']) for key in db: print(key, ":\n ", db[key]) ### Ändern db['kuchen3']=kuchen('Nusskuchen',14) db['kommentar']="Es reicht für die Feier." db.close() print "--------------------" ### print "Shelve geändert ..." db=shelve.open('kuchen') print(len(db), " Einträge") for key in db: print(key, " :\n",db[key]) Man kann an den Beispielen noch etwas mehr lernen: * Wenn man im Python-Interpreter "print(o)" eingibt, so wird das Objekt o angezeigt, wenn es dafür eine Anzeigemethode gibt. Für Zahlen, Strings, Arrays, etc. sind diese vordefiniert. Wenn wir aber selber eine Klasse schreiben, so können wir mit der Methode __str__(self) einen Ausgabe-String definieren. * Ist k ein Objekt der Klasse 'kuchen', so können wird help(k) uns die für k definierten Attribute und Methoden samt der Doc-Strings anzeigen.