Hi,
ich hab eine frage:
ich hab mir ein Telefonbuch gebastelt, in das man einträge speichern kann. Ich kann sie speichern aber nicht laden. Gearbeitet hab ich mit einem dictionairy (mydict={} - sowas)
beim laden gibt es dann die fehlermeldung:
"Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Programme\Python\lib\lib-tk\Tkinter.py", line 1403, in __call__
return self.func(*args)
File "C:\Dokumente und Einstellungen\Markus Naumann\Eigene Dateien\Informatik\Fertige Programme\Tkinter\Telefonbuch\telefonliste.pyw", line 36, in neu
for Name,Nummer in mydict.items():
AttributeError: 'str' object has no attribute 'items' "
weiß das jemand wie man das macht? ^^
MFG
Markus
Lists/Dicts aus einer Textdatei laden?
-
- User
- Beiträge: 419
- Registriert: Sonntag 3. September 2006, 15:11
- Wohnort: in den weiten von NRW
- Kontaktdaten:
Hi,
Nach der Fehlermeldung schätze ich mal, dass du die Datei liest, und dann sofort darauf zugreifst? Du musst aus der Zeichenkette erstmal ein Dictionary machen. Entweder mit eval(), oder mit mit dem Modul pickle, wobei du die Daten dann auch damit abspeichern musst.
Gruß, jj
Nach der Fehlermeldung schätze ich mal, dass du die Datei liest, und dann sofort darauf zugreifst? Du musst aus der Zeichenkette erstmal ein Dictionary machen. Entweder mit eval(), oder mit mit dem Modul pickle, wobei du die Daten dann auch damit abspeichern musst.
Gruß, jj
Nun die Fehlermeldung sagt schonmal das eine Zeichenkette keine Methode mit dem Namen `items()` hat.
Du hast also wahrscheinlich die Datei als Zeichenkette eingelesen und an den Namen `mydict` gebunden. Mal so geraten weil Du ja keinen Quelltext dazu gezeigt hast.
Das `pickle`-Modul bietet sich immer an, wenn man auf einfache Art und Weise Python-Objekte in Dateien speichern und später wieder herstellen möchte.
Du hast also wahrscheinlich die Datei als Zeichenkette eingelesen und an den Namen `mydict` gebunden. Mal so geraten weil Du ja keinen Quelltext dazu gezeigt hast.
Das `pickle`-Modul bietet sich immer an, wenn man auf einfache Art und Weise Python-Objekte in Dateien speichern und später wieder herstellen möchte.
- nkoehring
- User
- Beiträge: 543
- Registriert: Mittwoch 7. Februar 2007, 17:37
- Wohnort: naehe Halle/Saale
- Kontaktdaten:
um mal n bissl Licht in die Sache zu bringen:
Code: Alles auswählen
>>> type(file(dateiname, 'r').read()))
<type 'str'>
[url=http://www.python-forum.de/post-86552.html]~ Wahnsinn ist auch nur eine andere Form der Intelligenz ~[/url]
hackerkey://v4sw6CYUShw5pr7Uck3ma3/4u7LNw2/3TXGm5l6+GSOarch/i2e6+t2b9GOen7g5RAPa2XsMr2
hackerkey://v4sw6CYUShw5pr7Uck3ma3/4u7LNw2/3TXGm5l6+GSOarch/i2e6+t2b9GOen7g5RAPa2XsMr2
ja stimmt, also hier der Quelltext:
[/code]
@ nkoehring: was genau bedeutet das type?
Danke im Voraus
Code: Alles auswählen
[code=]from Tkinter import*
from ScrolledText import*
mydict={}
einträge=0
x='unbelegt'
mydict=type(file('mydict.txt', 'r').read())
datei2=open('einträge.txt','r')
einträge=int(datei2.read())
def check():
global name,nummer
name=eingabe_name.get()
nummer=eingabe_nummer.get()
if name=='':
eingabe_name.config(bg='red')
else:
eingabe_name.config(bg='white')
if nummer=='':
eingabe_nummer.config(bg='red')
else:
eingabe_nummer.config(bg='white')
def neu():
global einträge,x,name,nummer
check()
if name!='' and nummer!='':
name=name.upper()
datei=open('mydict.txt','w')
datei2=open('einträge.txt','w')
l_status.config(text='Speichervorgang erfolgreich!')
for Name,Nummer in mydict.items():
if Name==name:
x='belegt'
if x=='unbelegt':
einträge=einträge+1
l_einträge.config(text='Einträge = '+str(einträge))
l_kontakt.config(text=str(name)+' : '+str(nummer))
mydict[name]=nummer
datei.write(str(mydict))
datei2.write(str(einträge))
x='unbelegt'
def laden():
global name,nummer
name=eingabe_name.get()
nummer=eingabe_nummer.get()
l_kontakt.config(text='')
if name=='' and nummer=='':
l_status.config(text='Mindestangabe: Name oder Nummer!')
elif name!='' and nummer!='':
l_status.config(text='Nur Name oder Nummer angeben!')
elif name!='':
for Name,Nummer in mydict.items():
if name==Name:
l_kontakt.config(text=str(Name)+' : '+str(Nummer))
break
elif nummer!='':
for Name,Nummer in mydict.items():
if nummer==Nummer:
l_kontakt.config(text=str(Name)+' : '+str(Nummer))
break
def alles_laden():
ausgabe=''
f2=Tk()
f2.title('Anzeigen aller Kontakte')
frame2=Frame(f2,bg='LightsteelBlue',height=400,width=400)
frame2.pack()
l_überschrift2=Label(frame2,bg='grey',font=('Arial',14,'bold'),width=20,relief='raised',text='Alles Kontakte:')
l_überschrift2.place(x=20,y=20)
ausgabefeld=ScrolledText(frame2,bg='Lavender',font=('Arial',10,'bold'),width=50,height=20)
for Name,Nummer in mydict:
ausgabe=ausgabe+str(Name)+(30-len(Name))*' '+': '+str(Nummer)+'\n'
ausgabefeld.insert(END,ausgabe)
ausgabefeld.place(x=20,y=60)
l_kontakt.config(text='')
def alles_loeschen():
global mydict,einträge
mydict={}
einträge=0
datei=open('einträge.txt','w')
datei.write(str(einträge))
datei2=open('mydict.txt','w')
datei2.write(str(mydict))
l_einträge.config(text='Einträge = '+str(einträge))
l_status.config(text='Löschvorgang erfolgreich!')
l_kontakt.config(text='')
hf=Tk()
hf.title('Telefonliste')
frame1=Frame(hf,bg='PaleGreen',height=400,width=400)
frame1.pack()
l_überschrift=Label(frame1,bg='PaleGreen',font=('Arial',30,'bold'),text='Telefonliste')
l_überschrift.place(x=90,y=20)
l_einträge=Label(frame1,bg='PaleGreen',font=('Arial',12,'bold'))
l_einträge.place(x=140,y=70)
l_einträge.config(text='Einträge = '+str(einträge))
l_name=Label(frame1,bg='grey',font=('Arial',14,'bold'),text='Name:',relief='raised')
l_name.place(x=30,y=100)
eingabe_name=Entry(frame1,width=20,font=('Arial',12,'bold'))
eingabe_name.place(x=50,y=140)
l_nummer=Label(frame1,bg='grey',font=('Arial',14,'bold'),text='Nummer:',relief='raised')
l_nummer.place(x=30,y=190)
eingabe_nummer=Entry(frame1,width=20,font=('Arial',12,'bold'))
eingabe_nummer.place(x=50,y=230)
b_neu=Button(frame1,bg='Chartreuse',font=('Arial',10,'bold'),width=15,text='Neu anlegen!',command=neu)
b_neu.place(x=255,y=120)
b_laden=Button(frame1,bg='Chartreuse',font=('Arial',10,'bold'),width=15,text='Kontakt anzeigen!',command=laden)
b_laden.place(x=255,y=160)
b_alles_laden=Button(frame1,bg='Chartreuse',font=('Arial',10,'bold'),width=15,text='Alles laden!',command=alles_laden)
b_alles_laden.place(x=255,y=200)
b_alles_loeschen=Button(frame1,bg='Chartreuse',font=('Arial',10,'bold'),width=15,text='Alles löschen!',command=alles_loeschen)
b_alles_loeschen.place(x=255,y=240)
l_status=Label(frame1,bg='PaleGreen',width=28,font=('Arial',14,'bold'))
l_status.place(x=30,y=290)
l_kontakt=Label(frame1,bg='PaleGreen',width=30,font=('Arial',13,'bold'))
l_kontakt.place(x=30,y=350)
myphoto=PhotoImage(file='telefon.gif')
L=Label(frame1,image=myphoto)
L.config(width=myphoto.width(), height=myphoto.height())
L.place(x=0,y=0)
@ nkoehring: was genau bedeutet das type?
Danke im Voraus
@Markus12: Du solltest wirklich das `pickle`-Modul zum speichern und laden benutzen. Und dabei nicht vergessen die Dateien im Binärmodus zu öffnen.
So wie's da jetzt steht speicherst Du die Daten überhaupt nicht, Du öffnest nur Dateien zu schreiben. Ohne sie wieder zu schliessen.
Erst dachte ich die Anzahl der Einträge musst Du nicht in einer extra Datei speichern weil man mit `len()` die Anzahl der Elemente eines Dictionary erfährt, bis ich gesehen habe, dass Du auch "unbelegte" Einträge hast ─ warum machst Du so etwas?
So wie's da jetzt steht speicherst Du die Daten überhaupt nicht, Du öffnest nur Dateien zu schreiben. Ohne sie wieder zu schliessen.
Erst dachte ich die Anzahl der Einträge musst Du nicht in einer extra Datei speichern weil man mit `len()` die Anzahl der Elemente eines Dictionary erfährt, bis ich gesehen habe, dass Du auch "unbelegte" Einträge hast ─ warum machst Du so etwas?
@ BlackJack:
Ja, du hast recht, hab ich vergessen, dass ich die einträgeanzahl nicht extra in eine datei schreiben muss
Ja, mittlerweile hab ich gemerkt dass man, wenn man die datei nicht schließt, die datei auch nicht verschieben kann.
Was meinst du mit unbelegt?
Meinst du das?
Oder Dictionairy EInträge? Und wo sind sie? ^^
Danke für die Hilfe!
Ja, du hast recht, hab ich vergessen, dass ich die einträgeanzahl nicht extra in eine datei schreiben muss
Ja, mittlerweile hab ich gemerkt dass man, wenn man die datei nicht schließt, die datei auch nicht verschieben kann.
Was meinst du mit unbelegt?
Meinst du das?
Code: Alles auswählen
for Name,Nummer in mydict.items():
if Name==name:
x='belegt'
if x=='unbelegt':
einträge=einträge+1
l_einträge.config(text='Einträge = '+str(einträge))
l_kontakt.config(text=str(name)+' : '+str(nummer))
mydict[name]=nummer
datei.write(str(mydict))
datei2.write(str(einträge))
x='unbelegt'
Oder Dictionairy EInträge? Und wo sind sie? ^^
Danke für die Hilfe!
@ EyDu:
Aber der Tipp war nicht schlecht!
Ja, ich weiß , aber die Doku ist auf Englisch und ich verstehe es einfach nicht so richtig (die ganze dokumentation) ^^Da fragt man sich ja, was länger dauert: Die Frage zu schreiben oder einfach mal selber in der Doku nachlesen? Wink
Aber der Tipp war nicht schlecht!
habe ich dich jetzt recht verstanden, dass du einproblem mit pickle hast?
ist ganz einfach, probier mal:
ist ganz einfach, probier mal:
Code: Alles auswählen
dict = { ... }
# schreiben ...
output = open('data.pkl', 'wb')
pickle.dump(dict, output)
output.close()
# ... und lesen
input = open('data.pkl', 'rb')
data1 = pickle.load(input)
schön
ich weis ja nicht, wie ernsthaft du dich mit der programmierung auseinandersetzen willst, aber um englisch kommst du dabei eigentlich nicht rum.
das schöne ist, dass man zum lesen von fachliteratur eigentlich nur vokabeln braucht. und das ist ja gerade am computer einfach: du nimmst dir ein tool wie babylon her und hast mit einem click die übersetzung eines englischen wortes.
am anfang ist das natürlich noch etwas anstrengend, geht aber immer besser.
ich komme inzwischen besser mit englischen büchern zurecht als mit deutschen, da vor allem die amerikaner nicht soviel wert darauf legen wie deutsche fahcexperten möglichst komplizierte sätze zu bauen.
ich weis ja nicht, wie ernsthaft du dich mit der programmierung auseinandersetzen willst, aber um englisch kommst du dabei eigentlich nicht rum.
das schöne ist, dass man zum lesen von fachliteratur eigentlich nur vokabeln braucht. und das ist ja gerade am computer einfach: du nimmst dir ein tool wie babylon her und hast mit einem click die übersetzung eines englischen wortes.
am anfang ist das natürlich noch etwas anstrengend, geht aber immer besser.
ich komme inzwischen besser mit englischen büchern zurecht als mit deutschen, da vor allem die amerikaner nicht soviel wert darauf legen wie deutsche fahcexperten möglichst komplizierte sätze zu bauen.
Das mit dem Pickel funktioniert
Ich habe wieder einmal ein problem:
Wenn ich mein Programm aufrufe und alles anzeigen möchte klappt alles, aber wenn ich einen Kontakt hinzugefügt habe, dann kann öffnet er alle Kontakte nicht mehr mit einer Fehlermeldung
Fehlermeldung:
File "C:\Dokumente und Einstellungen\Markus Naumann\Eigene Dateien\Informatik\Fertige Programme\Tkinter\Telefonbuch\telefonliste.pyw", line 74, in alles_laden
for Name,Nummer in mydict.items():
AttributeError: 'NoneType' object has no attribute 'items'
Also das ist der Quelltext bis jetzt:
Ich habe wieder einmal ein problem:
Wenn ich mein Programm aufrufe und alles anzeigen möchte klappt alles, aber wenn ich einen Kontakt hinzugefügt habe, dann kann öffnet er alle Kontakte nicht mehr mit einer Fehlermeldung
Fehlermeldung:
File "C:\Dokumente und Einstellungen\Markus Naumann\Eigene Dateien\Informatik\Fertige Programme\Tkinter\Telefonbuch\telefonliste.pyw", line 74, in alles_laden
for Name,Nummer in mydict.items():
AttributeError: 'NoneType' object has no attribute 'items'
Also das ist der Quelltext bis jetzt:
Code: Alles auswählen
from Tkinter import*
from ScrolledText import*
import pickle
mydict={}
einträge=0
x='unbelegt'
datei=open('mydict.pkl','rb')
mydict=pickle.load(datei)
einträge=len(mydict)
def check():
global name,nummer
name=eingabe_name.get()
nummer=eingabe_nummer.get()
if name=='':
eingabe_name.config(bg='red')
else:
eingabe_name.config(bg='white')
if nummer=='':
eingabe_nummer.config(bg='red')
else:
eingabe_nummer.config(bg='white')
def neu():
global name,nummer,mydict,einträge,x
check()
if name!='' and nummer!='':
name=name.upper()
for Name,Nummer in mydict.items():
if Name==name:
x='belegt'
if x=='unbelegt':
einträge=einträge+1
mydict[name]=nummer
datei=open('mydict.pkl','wb')
mydict=pickle.dump(mydict,datei)
datei.close()
l_einträge.config(text='Einträge = '+str(einträge))
l_kontakt.config(text=str(name)+' : '+str(nummer))
l_status.config(text='Speichervorgang erfolgreich!')
x='unbelegt'
def laden():
global name,nummer
name=eingabe_name.get()
nummer=eingabe_nummer.get()
l_kontakt.config(text='')
if name=='' and nummer=='':
l_status.config(text='Mindestangabe: Name oder Nummer!')
elif name!='' and nummer!='':
l_status.config(text='Nur Name oder Nummer angeben!')
elif name!='':
for Name,Nummer in mydict.items():
if name==Name:
l_kontakt.config(text=str(Name)+' : '+str(Nummer))
break
elif nummer!='':
for Name,Nummer in mydict.items():
if nummer==Nummer:
l_kontakt.config(text=str(Name)+' : '+str(Nummer))
break
def alles_laden():
ausgabe=''
f2=Tk()
f2.title('Anzeigen aller Kontakte')
frame2=Frame(f2,bg='LightsteelBlue',height=400,width=400)
frame2.pack()
l_überschrift2=Label(frame2,bg='grey',font=('Arial',14,'bold'),width=20,relief='raised',text='Alles Kontakte:')
l_überschrift2.place(x=20,y=20)
ausgabefeld=ScrolledText(frame2,bg='Lavender',font=('Arial',10,'bold'),width=50,height=20)
for Name,Nummer in mydict.items():
ausgabe=ausgabe+str(Name)+(30-len(Name))*' '+': '+str(Nummer)+'\n'
ausgabefeld.insert(END,ausgabe)
ausgabefeld.place(x=20,y=60)
l_kontakt.config(text='')
def alles_loeschen():
global mydict,einträge
mydict={}
einträge=0
data='(dp0','\n','.'
datei=open('mydict.pkl','w')
datei.write(str(data))
datei.close()
l_einträge.config(text='Einträge = '+str(einträge))
l_status.config(text='Löschvorgang erfolgreich!')
l_kontakt.config(text='')
hf=Tk()
hf.title('Telefonliste')
frame1=Frame(hf,bg='PaleGreen',height=400,width=400)
frame1.pack()
l_überschrift=Label(frame1,bg='PaleGreen',font=('Arial',30,'bold'),text='Telefonliste')
l_überschrift.place(x=90,y=20)
l_einträge=Label(frame1,bg='PaleGreen',font=('Arial',12,'bold'))
l_einträge.place(x=140,y=70)
l_einträge.config(text='Einträge = '+str(einträge))
l_name=Label(frame1,bg='grey',font=('Arial',14,'bold'),text='Name:',relief='raised')
l_name.place(x=30,y=100)
eingabe_name=Entry(frame1,width=20,font=('Arial',12,'bold'))
eingabe_name.place(x=50,y=140)
l_nummer=Label(frame1,bg='grey',font=('Arial',14,'bold'),text='Nummer:',relief='raised')
l_nummer.place(x=30,y=190)
eingabe_nummer=Entry(frame1,width=20,font=('Arial',12,'bold'))
eingabe_nummer.place(x=50,y=230)
b_neu=Button(frame1,bg='Chartreuse',font=('Arial',10,'bold'),width=15,text='Neu anlegen!',command=neu)
b_neu.place(x=255,y=120)
b_laden=Button(frame1,bg='Chartreuse',font=('Arial',10,'bold'),width=15,text='Kontakt anzeigen!',command=laden)
b_laden.place(x=255,y=160)
b_alles_laden=Button(frame1,bg='Chartreuse',font=('Arial',10,'bold'),width=15,text='Alles laden!',command=alles_laden)
b_alles_laden.place(x=255,y=200)
b_alles_loeschen=Button(frame1,bg='Chartreuse',font=('Arial',10,'bold'),width=15,text='Alles löschen!',command=alles_loeschen)
b_alles_loeschen.place(x=255,y=240)
l_status=Label(frame1,bg='PaleGreen',width=28,font=('Arial',14,'bold'))
l_status.place(x=30,y=290)
l_kontakt=Label(frame1,bg='PaleGreen',width=30,font=('Arial',13,'bold'))
l_kontakt.place(x=30,y=350)
myphoto=PhotoImage(file='telefon.gif')
L=Label(frame1,image=myphoto)
L.config(width=myphoto.width(), height=myphoto.height())
L.place(x=0,y=0)
fehlt in zeile 34 nicht eine einrückung?
der fehler liegt in zeile 38.
pickle.dump gibt None zurück, daher ist ab jetzt mydict None!
du solltest auch nicht bei jedem update serialisieren, mach das wenn du das programm beendest.
was hast du vor mit dem programm, wo soll es eingesetzt werden?
der fehler liegt in zeile 38.
pickle.dump gibt None zurück, daher ist ab jetzt mydict None!
du solltest auch nicht bei jedem update serialisieren, mach das wenn du das programm beendest.
was hast du vor mit dem programm, wo soll es eingesetzt werden?
pickle.dump(variable, datei) schreibt eine python variable in eine datei.
die funktion hat keinen rückgabewert - was soll sie auch zurückgeben, ausser evtl. einen status, und den willst du sicher nicht in deinem dict stehen haben.
anders pickle.load(datei), es liest eine (oder mehrere) variablen aus einer datei.
rückgabewert ist die gelesene variable. hast du ja auch richtig verwendet.
dann bring das programm mal zum laufen, viel glück
wenn du dann immernoch spass am programmieren hast, wäre es zeit für ein refactoring
die funktion hat keinen rückgabewert - was soll sie auch zurückgeben, ausser evtl. einen status, und den willst du sicher nicht in deinem dict stehen haben.
anders pickle.load(datei), es liest eine (oder mehrere) variablen aus einer datei.
rückgabewert ist die gelesene variable. hast du ja auch richtig verwendet.
dann bring das programm mal zum laufen, viel glück
wenn du dann immernoch spass am programmieren hast, wäre es zeit für ein refactoring
Huiuiui,
gerade wenn Du Python programmieren lernen möchtest, mein Tipp wäre das Du Dich dennoch vorher mit ein paar Dingen wie:
- Objektorientierung (u. solche in Python)
- Model-View-Control Konzept
- Modularisierung (u. solche in Python)
auseinander setzen solltest.
Du möchtest eine kleine grafische Oberfläche gestalte, welches eigentich schon ein recht gutes Programm darstellen könnte, nutzt aber Techniken des einfachen Scriptens.
Python kann mehr als sequentiell aus einer Datei Funktionsaufrufe durchzuführen und Methodendefinitionen zuzulassen.
Du könntest Dein Script in mindestens in zwei Klassen, wenn nicht sogar mehrere Module zerlegen:
- Speicher (eine Klasse, welche Zugriffsmethoden wie "spechere_satz, lese_satz, update_satz, hole_liste, etc.")
- Oberfläche (als Klasse, um schön die Klassenvariablen anstellen der bösen gobals nutzen zu können)
- etc.
Wenn Du für Deinen einen einheitlichen Methodenumfang für die Oberflächenklasse definierst, wäre es für Dich z.B. später auch kein Problem anstelle des Picklens in eine Datei mit einer Datenbank zu arbeiten.
Einfach eine Klasse schreiben, welche die gleichen Funktionalitäten anbietet und das Verhalten auf den Datenbankadapter umbricht .. voilla.
Viel Spass auf jeden Fall noch beim Python lernen
gerade wenn Du Python programmieren lernen möchtest, mein Tipp wäre das Du Dich dennoch vorher mit ein paar Dingen wie:
- Objektorientierung (u. solche in Python)
- Model-View-Control Konzept
- Modularisierung (u. solche in Python)
auseinander setzen solltest.
Du möchtest eine kleine grafische Oberfläche gestalte, welches eigentich schon ein recht gutes Programm darstellen könnte, nutzt aber Techniken des einfachen Scriptens.
Python kann mehr als sequentiell aus einer Datei Funktionsaufrufe durchzuführen und Methodendefinitionen zuzulassen.
Du könntest Dein Script in mindestens in zwei Klassen, wenn nicht sogar mehrere Module zerlegen:
- Speicher (eine Klasse, welche Zugriffsmethoden wie "spechere_satz, lese_satz, update_satz, hole_liste, etc.")
- Oberfläche (als Klasse, um schön die Klassenvariablen anstellen der bösen gobals nutzen zu können)
- etc.
Wenn Du für Deinen einen einheitlichen Methodenumfang für die Oberflächenklasse definierst, wäre es für Dich z.B. später auch kein Problem anstelle des Picklens in eine Datei mit einer Datenbank zu arbeiten.
Einfach eine Klasse schreiben, welche die gleichen Funktionalitäten anbietet und das Verhalten auf den Datenbankadapter umbricht .. voilla.
Viel Spass auf jeden Fall noch beim Python lernen
ich denke nicht, dass es sinnvoll ist sich mit diesen ganzen konzepten auseinander zu setzen, bevor man es nicht mindestens einmal "falsch" gemacht hat.
wenn du einem einsteiger gleich das MVC um die ohren schlägst bekommt ders ja mit der angst zu tun
wenn du einem einsteiger gleich das MVC um die ohren schlägst bekommt ders ja mit der angst zu tun
@ Markus
Vielleicht hilft dir noch folgende Hilfestellung beim Aufbau und der Optimierung deines Programmes.
In Python ist es möglich "Objektorientiert" zu programmieren. Hier im Forum gibt es einige gute Posts, die sich damit beschäftigen.
Mein Tipp wäre die Unterteilung Deiner Anwendung in sagen wir einmal mindestens zwei Klassen.
Ebenfalls erlaubt es eine klare Trennung zwischen der reinen Oberfläche und dem Datei-Pickle-Speicher, wodurch das Entwickeln und Testen für Dich um einiges leichter und durchschaubarer werden sollte.
Hier z.B: eine solche Oberflächenklasse:
und hier beispielhaft noch für den Zugriff auf den Datei-Pickle-Speicher:
Ein schönes Beispiel für eine solche konzeptionelle Unterteilung zwischen Darstellung mit Logik und der Datenebene, ist dieses Codesbeispiel von Gerold um [wiki=CPU_Anzeige_(win32)]CPU-Auslastung anzuzeigen[/wiki].
Weicht ein wenig alles von deiner ursprünglichen Fragestellung bezüglich des Datei-Picklens ab ... aber ... glaub mir, so hättest Du es ein wenig einfacher und überschaulicher (gerade auch in Bezug auf das Entwickeln, Testen, Nachfragen im Forum, etc. bezüglich der Pickle-Speicher-Komponente).
Gruß,
>>Masaru<<
Vielleicht hilft dir noch folgende Hilfestellung beim Aufbau und der Optimierung deines Programmes.
In Python ist es möglich "Objektorientiert" zu programmieren. Hier im Forum gibt es einige gute Posts, die sich damit beschäftigen.
Mein Tipp wäre die Unterteilung Deiner Anwendung in sagen wir einmal mindestens zwei Klassen.
- - grafische Oberfläche
- Dateizugriffe
Ebenfalls erlaubt es eine klare Trennung zwischen der reinen Oberfläche und dem Datei-Pickle-Speicher, wodurch das Entwickeln und Testen für Dich um einiges leichter und durchschaubarer werden sollte.
Hier z.B: eine solche Oberflächenklasse:
Code: Alles auswählen
from Tkinter import*
# Definition der Farben durch Konstanten (Vorteil: wenn Du einmal die
# Farbe aendern moechtest, musst Du nicht alle Strings anpassen, sondern
# nur diese Konstanten.
FARBE_LABLE_NORMAL = 'white'
FARBE_LABLE_WARNUNG = 'red'
class TelefonBuch(Tk):
"""Grafische Oberflaeche und Programmlogik"""
def __init__(self):
Tk.__init__(self)
self.title('Telefonlisten Verwaltung')
frame = Frame(self, bg='PaleGreen', height=400, width=400)
frame.pack()
self.__eintrage = 0 # anstelle mit "globals" kannst Du viel effektiver die Variable so als Klassenvariable nutzen
self.__load_statische_elemente(frame)
self.__load_dynamische_elemente(frame)
self.__mein_daten_speicher = MeinDatenSpeicher('mydict.pkl') # die nachste von mir angesprochene Klasse ;)
# ....
def __load_statische_elemente(self, frame):
l_ueberschrift = Label(frame, bg='PaleGreen', font=('Arial',30,'bold'), text='Telefonliste')
l_ueberschrift.place(x=90, y=20)
# ...
def __load_dynamische_elemente(self, frame):
self.__eingabe_name = Entry(frame, width=20, font=('Arial',12,'bold'))
self.__eingabe_name.place(x=50, y=140)
self.__eingabe_nummer = Entry(frame, width=20, font=('Arial',12,'bold'))
self.__eingabe_nummer.place(x=50, y=23
#...
def __get_name_nummer(self)
"""Liefert die Werte der Felder Name und Nummer zurueck,
und faerbt bei Fehlerhaften Eingaben eventuell """
name = self.__eingabe_name.get()
nummer = self.__eingabe_nummer.get()
if not name:
self.__eingabe_name.config(bg=FARBE_LABLE_NORMAL)
else:
self.__eingabe_name.config(bg=FARBE_LABLE_WARNUNG)
if not nummer:
self.__eingabe_nummer.config(bg=FARBE_LABLE_WARNUNG)
else:
self.__eingabe_nummer.config(bg=FARBE_LABLE_NORMAL)
return name, nummer
def self.__neu(self):
"""Methode hinter dem Button 'neu'"""
name, nummer = self.__get_name_nummer()
# ...
if name in self.__mein_daten_speicher.liste_alle_namen():
# ...
if nummer in self.__mein_daten_speicher.liste_alle_nummern():
# ...
erfolgt = self.__mein_daten_speicher.schreibe_daten(name, nummer)
if erfolgt:
return True
else:
self.__faerbe_fehler(
"Konnte '%s' mit Nummber '%s' nicht eintragen." % (name, nummer))
# ...
Code: Alles auswählen
import pickle
import os
class MeinDatenSpeicher(object):
"""Datenspeicher Klasse, um auf Daten in einer Datei zuzugreifen,
bzw. letztendlich persistent zu halten"""
def __init__(self, dateipfad):
self.__datei_pfad = dateipfad
self.__datei_objekt = None
self.__speicher_inhalt = None
self.__lade_speicher()
self.__aktualisiere_speicher()
def __lade_speicher(self):
if not os.path.isfile(self.__datei_pfad):
self.__datei_objekt = open(self.__datei_pfad, 'w+')
self.__aktualisiere_speicher()
def __aktualisiere_speicher(self):
self.__speicher_inhalt = pickle.load(self.__datei)
def schreibe_daten(self, name, nummer):
self.__aktualisiere_speicher()
if name in self.__speicher_inhalt.keys():
return False
if nummer in self.__speicher_inhalts.values():
return False
return True
def liste_speicher(self):
self.__aktualisiere_speicher()
return self.__speicher_inhalt
Weicht ein wenig alles von deiner ursprünglichen Fragestellung bezüglich des Datei-Picklens ab ... aber ... glaub mir, so hättest Du es ein wenig einfacher und überschaulicher (gerade auch in Bezug auf das Entwickeln, Testen, Nachfragen im Forum, etc. bezüglich der Pickle-Speicher-Komponente).
Gruß,
>>Masaru<<