frage zu pickle

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
cyp++
User
Beiträge: 69
Registriert: Freitag 22. September 2006, 13:54

Sonntag 17. Dezember 2006, 12:34

hallo,

ich habe ein kleines problem mit dem modul "pickle" undzwar will es nicht richtig funktionieren bzw nicht richtig laden, ob es richtig speichert weiß ich auch nicht so recht, da ich ja auch nichts laden kann. Es geht eigentlich nur um die ersten beiden funktionen "saveVoc()" und "loadDict()" der Rest funktioniert einwandfrei, wenn ihr natürlich noch Verbesserungsvorschläge habt, immer her damit! :D Hier erstmal mein Code:

Code: Alles auswählen

import pickle

def saveVoc():
    f = file('dict.dmp', 'w')
    pickle.dump(dict,f)
    f.close()

def loadDict():
    f = file('dict.dmp', 'r')
    pickle.load(f)
    f.close()

def writeVocIntoDict():
    word = raw_input('\nEnter the word: ')
    transword = raw_input('\nEnter the translation: ')
    dict[word] = transword
    # translated word as key
    dict[transword] = word
    saveVoc()


def menu():
    print '1) Add vocabulary'
    print '2) Translate a word'
    sel = int(raw_input ('\nWhat do you want? '))
    if sel >= 1 and sel < 3:
        if sel == 1:
            writeVocIntoDict()
        elif sel == 2:
            word = raw_input('Enter the word: ')
            if word in dict:
                print dict[word]
            else:
                print 'vocabulary not known'
    else:
        print 'Error! Only numbers from 1 to 2 are allowed!'

    menu()


dict = {}

print '\nDictionary 1.000.000 by read error\n**********************************'
loadDict()
menu()
mfg
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Sonntag 17. Dezember 2006, 12:47

cyp++ hat geschrieben:

Code: Alles auswählen

i
def loadDict():
    f = file('dict.dmp', 'r')
    pickle.load(f)
    f.close()
Ja, das lädt von "f", aber wohin? Du wirfst den Rückgabewert von pickle.load() einfach weg. loadDict gibt None zurück.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
cyp++
User
Beiträge: 69
Registriert: Freitag 22. September 2006, 13:54

Sonntag 17. Dezember 2006, 13:06

ok, habe jetzt folgendes:

Code: Alles auswählen

def loadDict():
    f = file('dict.dmp', 'r')
    load = pickle.load(f)
    f.close()
und nu? wie ruf das ich nu auf? normal wie ich es vorher auch getan habe oder muss ich noch irgendwas ändern? und muss ich bei saveVoc() auch ändern? weil da habe ich ja auch nur

Code: Alles auswählen

pickle.dump(dict,f)
ohne irgendeine zuweisung?
BlackJack

Sonntag 17. Dezember 2006, 13:35

cyp++ hat geschrieben:ok, habe jetzt folgendes:

Code: Alles auswählen

def loadDict():
    f = file('dict.dmp', 'r')
    load = pickle.load(f)
    f.close()
und nu? wie ruf das ich nu auf? normal wie ich es vorher auch getan habe oder muss ich noch irgendwas ändern?
Du wirfst die Daten immer noch weg. Das Dictionary wird jetzt geladen, an den Namen `load` gebunden, und der verschwindet am Ende der Funktion wieder und damit auch die geladenen Daten.

Code: Alles auswählen

def loadDict():
    f = file('dict.dmp', 'rb')
    result = pickle.load(f)
    f.close()
    return result
Beim schreiben solltest Du die Datei auch im Binärmodus öffnen und bitte benutze 1. keine globalen Variablen und 2. nicht den Namen `dict`, der überschreibt nämlich die eingebaute `dict()`-Funktion.

Werte sollten Funktionen möglichst nur über Argumente betreten und über Rückgabewerte verlassen. Sonst werden Programme sehr schnell unübersichtlich und Funktionen lassen sich nicht isoliert testen oder benutzen.
BlackJack

Sonntag 17. Dezember 2006, 14:01

cyp++ hat geschrieben:[...], wenn ihr natürlich noch Verbesserungsvorschläge habt, immer her damit!
Na dann, Du hast es ja so gewollt. :-)

Die Funktionsnamen halten sich nicht an die Konvention kleinbuchstaben_und_unterstriche.

Pickle-Dateien müssen als Binärdateien geöffnet werden, sonst sind sie nicht auf andere Plattformen übertragbar.

Das selbe Dictionary auch für "reverse lookup" zu benutzen, bringt spätestens Probleme wenn ein Wort in beiden Sprachen vorkommt, aber unterschiedliche Übersetzungen hat.

Bereichsabfragen kann man in Python auch ohne ``and`` ausdrücken: ``if 1 <= sel <= 2:``.

Eine einfache Endlosschleife durch Rekursion auszudrücken (`menu()`), ist in Python keine so gute Idee weil dabei irgendwann der Stack überläuft.
cyp++
User
Beiträge: 69
Registriert: Freitag 22. September 2006, 13:54

Sonntag 17. Dezember 2006, 14:27

Code: Alles auswählen

import pickle

def saveVoc():
    f = file('dict.dmp', 'w')
    save = pickle.dump(dict_,f)
    f.close()

def loadDict():
    f = file('dict.dmp', 'rb')
    result = pickle.load(f)
    f.close()
    return result

def writeVocIntoDict():
    word = raw_input('\nEnter the word: ')
    transword = raw_input('\nEnter the translation: ')
    dict_[word] = transword
    # translated word as key
    dict_[transword] = word
    saveVoc()


def menu():
    print '1) Add vocabulary'
    print '2) Translate a word'
    sel = int(raw_input ('\nWhat do you want? '))
    if 1 <= sel <= 2:
        if sel == 1:
            writeVocIntoDict()
        elif sel == 2:
            word = raw_input('Enter the word: ')
            if word in dict_:
                print dict_[word]
            else:
                print 'vocabulary not known'
    else:
        print 'Error! Only numbers from 1 to 2 are allowed!'

    menu()


dict_ = {}

print '\nDictionary 1.000.000 by read error\n**********************************'
loadDict()
menu()
Die Funktionsnamen halten sich nicht an die Konvention kleinbuchstaben_und_unterstriche.
sorry ich hab da was anderes gelernt, mir schwebt da irgendwas von UML vor..
Pickle-Dateien müssen als Binärdateien geöffnet werden, sonst sind sie nicht auf andere Plattformen übertragbar.
erledigt!
Das selbe Dictionary auch für "reverse lookup" zu benutzen, bringt spätestens Probleme wenn ein Wort in beiden Sprachen vorkommt, aber unterschiedliche Übersetzungen hat.
was meinst du damit? meinst du ich sollte, wenn ein wort hinzugefügt wird, es nicht ersetzen, sondern den neuen value anhängen?
Bereichsabfragen kann man in Python auch ohne ``and`` ausdrücken: ``if 1 <= sel <= 2:``.
erledigt!
Eine einfache Endlosschleife durch Rekursion auszudrücken (`menu()`), ist in Python keine so gute Idee weil dabei irgendwann der Stack überläuft.
wie kann ich das umgehen? sollte ich vll einfach eine option "beenden" hinzufügen zu menu() ?

es treten jetzt folgende tracebacks auf:

Code: Alles auswählen

Traceback (most recent call last):
  "[..]dict.py", line 45, in ?
  loadDict()
  "[..]dict.py", line 10, in loadDict
  result = pickle.load(f)
  File "E:\python\lib\pickle.py" , line 1390, in load
  return Unpickler(file).load()
  "[..]pickle.py", line 872, in load
  dispatch[key](self)
  "[..]pickle.py", line 980, in load_string
  raise ValueError, "insecure string pickle"
ValueError: insecure string pickle
:shock:
Zuletzt geändert von cyp++ am Sonntag 17. Dezember 2006, 14:36, insgesamt 1-mal geändert.
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Sonntag 17. Dezember 2006, 14:33

cyp++ hat geschrieben:
Die Funktionsnamen halten sich nicht an die Konvention kleinbuchstaben_und_unterstriche.
sorry ich hab da was anderes gelernt, mir schwebt da irgendwas von UML vor..
Was hat UML damit zu tun, wie deine Methoden heißen?
Das selbe Dictionary auch für "reverse lookup" zu benutzen, bringt spätestens Probleme wenn ein Wort in beiden Sprachen vorkommt, aber unterschiedliche Übersetzungen hat.
was meinst du damit? meinst du ich sollte, wenn ein wort hinzugefügt wird, es nicht ersetzen, sondern den neuen value anhängen?
Z.B.
englisch still <-> deutsch noch
deutsch still <-> englisch quiet

Da bekommst du Probleme. Es wäre also besser, zwei Dicts, für jede Richtung eines, zu verwenden.
Eine einfache Endlosschleife durch Rekursion auszudrücken (`menu()`), ist in Python keine so gute Idee weil dabei irgendwann der Stack überläuft.
wie kann ich das umgehen? sollte ich vll einfach eine option "beenden" hinzufügen zu menu() ?
Nein. Das Problem ist, dass menu() wieder menu() aufruft. In diesem Fall, wo die Funktion sich als letzten Schritt aufruft, nennt man das "tail recursion". In funktionalen Programmiersprachen ist das erwünscht, während man in Python lieber eine while-Schleife verwenden sollte.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Sonntag 17. Dezember 2006, 14:38

Ich habe deinen Code mal etwas umgeschrieben, findest ihn im LodgeIt. Ist allerdings ungetestet, da ich es aus dem Kopf gemacht habe (dafür habe ich ein paar Dinge kommentiert). Ansonsten müsste man wie BlackJack sagte, den Dictionary-Lookup ändern.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
Spaten
User
Beiträge: 52
Registriert: Samstag 27. Mai 2006, 11:35
Wohnort: Bremen
Kontaktdaten:

Sonntag 17. Dezember 2006, 21:50

..wenn ich als Tip am Rande anmerken darf:
es gibt außer dem Modul Pickle auch noch ein Modul
cPickle, dieses ist mit pickle komplett identisch, arbeitet aber schneller,
da es komplett in C implementiert ist.

Code: Alles auswählen

import cPickle
Python-Version: 2.5
Antworten