Inhalt von Entrys prüfen

Fragen zu Tkinter.
Antworten
bmh1980
gelöscht
Beiträge: 60
Registriert: Montag 26. Januar 2004, 17:13
Kontaktdaten:

Hallo zusammen.

Ich stehe wohl gerade auf dem Schlauch.

In meinem Skript sind mehrere Entrys, deren Inhalt in eine Datei geschrieben werden soll. Was ja auch schon funktioniert.

Allerdings müssen alle Entrys ausgefüllt werden. Ich dachte, dass ich dies so prüfen kann.

Code: Alles auswählen

name = self.entryName.get()
beschreibung = self.entryBeschreibung.get()
datei = file('pfad/zur/datei', 'w')
for text in [name, beschreibung]:
    if text != '':
        datei.write('Name: '+name)
        datei.write('Beschreibung: '+beschreibung)
Mir fällt gerade auf, dass es ja in der Form eher

Code: Alles auswählen

[...]
        datei.write(text)
[...]
heißen müsste, oder?

Wenn ja, wie könnte ich meinen Text mit einfügen?

Könnt ihr mir da weiterhelfen?

Marcus
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Hi bmh1980,

sehr verwirrend dein Code, und noch verwirrender deine Beschreibung.
Ich hab mal ein paar Fragen in den Code commentiert.

Code: Alles auswählen

name = self.entryName.get() #ok is klar holt name aus dem entry
beschreibung = self.entryBeschreibung.get() # auch klar holt bechreibung
datei = file('pfad/zur/datei', 'w')
for text in [name, beschreibung]: #??? warum iterierst du Text über name und beschreibung?
    if text != '': #angenommen name und beschreibung sind != ""
        datei.write('Name: '+name) #dann wird das und
        datei.write('Beschreibung: '+beschreibung)# das 2x gemacht
Du weisst schon was eine For-Schleife und was IF bewirken?


Gruß

Dookie
bmh1980
gelöscht
Beiträge: 60
Registriert: Montag 26. Januar 2004, 17:13
Kontaktdaten:

Für die Iteration habe ich mich entschieden, nachdem ich in meinem schlauen Buch nochmal das Kapitel über if und for Schleifen durchgelesen habe.

Was for und if bewirkt weiß ich schon. Denke ich.

Die for Schleife heißt so viel wie:
Für alles was folgt, führe Befehl aus.

if führt etwas aus, wenn die entsprechende Bedingung erfüllt ist.

Mein Problem ist, dass ich bisher nur einfache Bedingungen prüfen musste. Nicht so viel auf einmal.

Dazu kommt noch, dass ich bisher auch nur mit Shell-Skipten gearbeitet habe. Mit Python fange ich gerade erst an.

Zugegeben. Vieleicht ist ein GUI für den Anfang etwas zu viel. Aber bisher bin ich für meinen Geschmack recht weit gekommen. Nur so ein paar Feinheiten wie die ausgefüllten Felder machen mir noch Probleme.

Ich dachte zwar, dass ich mit dem Buch einiges lernen kann. Leider ist es nicht gerade verständlich. :(
Voges
User
Beiträge: 564
Registriert: Dienstag 6. August 2002, 14:52
Wohnort: Region Hannover

Hallo!
bmh1980 hat geschrieben:Mein Problem ist, dass ich bisher nur einfache Bedingungen prüfen musste. Nicht so viel auf einmal.
Ich denke mal, Du wolltest im Prinzip sowas:

Code: Alles auswählen

name = self.entryName.get()
beschreibung = self.entryBeschreibung.get()

if name+beschreibung != "":
    datei = file('pfad/zur/datei', 'w')
    datei.write('Name: '+name)
    datei.write('Beschreibung: '+beschreibung) 
    datei.close()
    
# Alternative if-Zeilen wären z.B.:
if name+beschreibung:    # denn ein leerer String ist auch gleichzeitig "UNWAHR"
if "" not in [name,beschreibung]:    # nützlich bei deutlich mehr zu prüfenden Strings
Jan
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Hallo nochmal,

Python ist bei Bedingungen sehr flexiebel
if not (text == beschreibung == ""): ginge auch genauso wie
if text != "" and beschreibung != "": oder, da ja ein, wie Voges schon schrieb, "" auch unwahr ist
if a and b:

Mit for kannst du etwas mit der sequence die dahinter ist anfangen.

Code: Alles auswählen

for i in ["Hallo", "Welt", "zum", 10000, "sten mal"]:
    print i,
einfach mal in der pythonconsole ausprobieren und rumspielen.

Gruß

Dookie
bmh1980
gelöscht
Beiträge: 60
Registriert: Montag 26. Januar 2004, 17:13
Kontaktdaten:

Voges hat geschrieben:

Code: Alles auswählen

if "" not in [name,beschreibung]:    # nützlich bei deutlich mehr zu prüfenden Strings
Das ist es! Gibt nämlich insgesamt 13 Entrys zu prüfen. Allerdings gibt es noch zusätzlich ein Text-Widget.

Im Test hat die if-Anweisung oben versagt. Muss ich für Text-Widgets etwas anderes machen, oder funktioniert das bei denen nicht?

Wenn ich schon am Fragen bin. Ich habe das Skript jetzt so erstellt, dass mit showerror eine Fehlermeldung angezeigt wird, sobald eines der Entrys leer ist. Gibt es da die Möglichkeit mit anzuzeigen, welche Entrys leer sind?

Ich nehme mal an, dass ich dafür eine Liste definieren müsste. Ich wüsste auch schon in etwa wie ich das bewerkstellige. Das würde mein Skript aber deutlich verlängern. Und daher wird das wahrscheinlich falsch sein. Oder zumindest umständlich.

Marcus
Voges
User
Beiträge: 564
Registriert: Dienstag 6. August 2002, 14:52
Wohnort: Region Hannover

Hallo!
bmh1980 hat geschrieben:Das ist es! Gibt nämlich insgesamt 13 Entrys zu prüfen.
Bei sovielen würde ich die Entry-Widgets von vornherein nicht an einzelne Variablen binden (name, beschreibung), sondern gleich in eine Liste packen:

Code: Alles auswählen

entries = []
entries.append(Entry(root,width=30))  # Nachname
entries.append(Entry(root,width=30))  # Vorname
entries.append(Entry(root,width=5))   # PLZ
entries.append(Entry(root,width=30))  # Ort
for e in entries:
    e.pack()
    
...

for e in entries:
    if e.get().strip() == "":
        pass  # irgendwas machen
Nur so als Anregung.

bmh1980 hat geschrieben:Im Test hat die if-Anweisung oben versagt. Muss ich für Text-Widgets etwas anderes machen, oder funktioniert das bei denen nicht?
Ein Text-Widget ist nie leer. Es enthält mindestens einen Zeilenumbruch (ist eben so). Aber auch bei den Entries würde ich immer berücksichtigen, dass u.U. jemand nur z.B. Leerzeichen eingegeben hat. Am besten Du bearbeitest die zurückgegebenen Strings vorm Prüfen auf "" mit der String-Methode strip().
Jan
bmh1980
gelöscht
Beiträge: 60
Registriert: Montag 26. Januar 2004, 17:13
Kontaktdaten:

Voges hat geschrieben:

Code: Alles auswählen

entries = []
entries.append(Entry(root,width=30))  # Nachname
entries.append(Entry(root,width=30))  # Vorname
entries.append(Entry(root,width=5))   # PLZ
entries.append(Entry(root,width=30))  # Ort
for e in entries:
    e.pack()
    
...

for e in entries:
    if e.get().strip() == "":
        pass  # irgendwas machen
Da ich beim Schreiben des Entry-Inhalts noch etwas hinzufüge, wie weiß ich denn, bei welchem Entry-Text etwas hinzugefügt werden muss?

Ich habe mir auch mal den Teil meines Buches durchgelesen, der strip() behandelt. Aber so ganz habe ich das noch nicht verstanden.

Werden dabei alle Leerzeichen entfernt? Wenn ja, dann hilft mir das nämlich nicht weiter. In dem Text-Widget muss eine längere Beschreibung eingegeben werden.

In meinem Buch gibt zwar Beispiele für lstrip(), rstrip() und strip(), aber bei den Beispielen befinden sich immer viele Leerzeichen am Anfang und am Ende des Strings. Und nicht mal zwischen drinn.

Marcus
Voges
User
Beiträge: 564
Registriert: Dienstag 6. August 2002, 14:52
Wohnort: Region Hannover

Hallo!
bmh1980 hat geschrieben:Da ich beim Schreiben des Entry-Inhalts noch etwas hinzufüge, wie weiß ich denn, bei welchem Entry-Text etwas hinzugefügt werden muss?
Um bei meinem Beispiel zu bleiben: Du weißt ja, dass das 3. Entry in der Liste die PLZ enthalten muss. Also: datei.write('Postleitzahl: '+ entries[2].get() + '\n')
Das ließe sich natürlich auch wiederum in einer Schleife erledigen, muss aber nicht sein.
bmh1980 hat geschrieben:Ich habe mir auch mal den Teil meines Buches durchgelesen, der strip() behandelt. Aber so ganz habe ich das noch nicht verstanden.

Werden dabei alle Leerzeichen entfernt?
Nein. Im Zweifelsfall ausprobieren oder in die Doku gucken (ggf. mit Wörterbuch in der Nähe). Das leading and trailing aus der Doku bedeutet, dass (nur) die führenden und anhängenden Zeichen gelöscht werden.

Jan
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Hi nochmal bmh1980,

ich habe beim programmieren immer eine Pythonkonsole offen. So kann ich, wenn ich wo nicht genau weiss was das macht, es einfach in der Konsole ausprobieren.
Unter Unix/Linux einfach eine Konsole öffnen und dort python eingeben. Jetht kannst Du alles Mögliche ausprobieren.

Code: Alles auswählen

>>> a = "       Testtext mit Leerzeichen und    Tabs  "
>>> print a
        Testtext mit Leerzeichen und    Tabs
>>> b = a.strip()
>>> print b
Testtext mit Leerzeichen und    Tabs
>>> print repr(a)
'\tTesttext mit Leerzeichen und\tTabs  '
>>> print repr(b)
'Testtext mit Leerzeichen und\tTabs'
>>>
Unter windows gehts glaub ich über ein Dosfenster.


Gruß

Dookie
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo bmh1980

Hier noch eine von unzähligen Möglichkeiten,
Informationen in ein Textfeld zu schreiben oder
dessen Inhalt abzuändern, in einer Datei abzuspeichern
und bei einem Neustart des Programms wieder automatisch
von der Datei zurück in die Textfelder zurückzulesen.
Das Programm enthält noch keine Filter Funktionen. Auch
die Focus Steuerung ist noch nicht integriert.

Ich verstand deine Frage evt. nicht korrekt. Aber
vielleicht kannst du eine deiner speziellen Funktionen noch
in das Skript integrieren, oder Funktionen aus diesem
Skript in deines exportieren.

Eine Eingabe bzw. Änderung wird nur abgespeichert, wenn
sie mit ENTER bestätigt wurde!

Slogan: PYTHON&TKINTER is a good combination!

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

# Application : Entryfields
# Version     : 1.00
# Autor       : wuf
# Datum       : 31.01.2004
# Geändert    : 31.01.2004

import  os
import  tkMessageBox
import  cPickle
from    Tkinter         import *

def CreateEntryLabel(parent,labellist):
	#~~ Erzeugt Eingabezeichnungen
	xpos,ypos = TOP_LEFT
	for label in labellist:
		lblobj = Label(parent,
					text   = label,
					anchor = E,
					padx   = 5,
					width  = 20,
					bd     = 1,
					relief = RAISED,
					bg     = parent['bg'],
					fg     = 'white',
					)
		lblobj.propagate(0)
		lblobj.pack()
		lblobj.place(x=xpos,y=ypos+2)
		ypos += 24 + YGAP

def CreateEntryField(parent,entrydata,entrylist):
	#~~ Erzeugt Eingabefeld
	xpos,ypos = TOP_LEFT
	for data in entrydata:
		entryfield = Entry(parent,
						width  = 15,
						)
		entryfield.propagate(0)
		entryfield.pack()
		entryfield.bind("<Return>",lambda e,Object=entryfield:TransferToEntryList(Object))
		entryfield.place(x=xpos+160,y=ypos)
		ypos += 24 + YGAP

		entryfield.insert(0,data)

		entrylist.append(entryfield)

# 	entryfield.insert(0,'Hello')
# 	entryfield.delete(0,last="end")
# 	print "data = ",entryfield.get()

def ReadEntryData():
	global eingabedaten

	#~~ Liest die Eingabedaten aus der Datei ein
	try:
		#~~ Versucht die Eingabedatendatei
		#   für das Lesen zu öffnen
		file = open(ENTRY_PATH + ENTRY_FILE,"r")
	except:
		#~~ Habe Probleme mit öffnen der Datei oder
		#   beim lesen der Eingabedaten!
		return(FALSE)
	#~~ Überträgt die Eingabedaten von der geöffneten
	#   Datei in die Liste für Eingabedaten
	eingabedaten = cPickle.load(file)
	file.close
	return(TRUE)

def WriteEntryData():
	global eingabedaten

	#~~ Lagert die Eingabedaten in die Datei aus
	if eingabedaten == None:
		#~~ Die Liste für Eingabedaten enthält
		#   keine Daten
		return(FALSE)

	try:
		#~~ Versucht die Eingabedatendatei
		#   für das Schreiben zu öffnen
		file = open(ENTRY_PATH + ENTRY_FILE,"w")
	except:
		#~~ Habe Probleme mit öffnen der Datei oder
		#   beim schreiben der Eingabedaten!
		print ENTRY_PATH + ENTRY_FILE
		return(FALSE)
	cPickle.dump(eingabedaten,file)
	file.close
	return(TRUE)

def TransferToEntryList(entryfield):
	global entryflag

	#~~ Setze Eingabeflag
	entryflag = TRUE

	#~~ Hole Index-Nr für das Eingabeobjekt
	index = eingabefelder.index(entryfield)

	#~~ Übertrage Eingabe vom Eingabefeld in
	#   die Eingabedatenliste
	eingabedaten[index] = entryfield.get()

def SaveEntry():
	global eingabedaten
	global entryflag

	if WriteEntryData() == FALSE:
			label = 'Eingabe Speichern'
			text  = 'Konnte die Eingabedaten nicht speichern!'
			tkMessageBox.showwarning(label,text)
	else:
		entryflag = FALSE

def ExitEntry():
	global entryflag

	#~~ Kontrolle ob die Eingabe gändert wurde
	if entryflag:
		#~~ Dialog: Die Eingabe wurde geändert
		msgbox = tkMessageBox.Message(root,
					type    = tkMessageBox.YESNO,
					icon    = tkMessageBox.QUESTION,
					title   = "Eingabe",
					message = "Soll die Änderung gespeichert werden?")
		antwort = msgbox.show()
		if antwort == "yes":
			#~~ Die Änderung wird gespeichert
			SaveEntry()
	#~~ Schliesst und entfernt das Hauptfenster der Anwendung
	root.destroy()
	sys.exit(0)

#******************************************************************
# ->> Versuchsprogramm für Eingabefelder <<-
#******************************************************************
if __name__ == '__main__':

	#~~ Es wird ein Tk-Hauptfenster generiert
	root = Tk()
	#~~ Vergrössere Fenster auf System Bildschirmgrösse
	root.maxsize(root.winfo_screenwidth(),root.winfo_screenheight())

	#~~ Eigenschaften für das Hauptfenster
	if os.name == 'nt':
		ScreenWidth  = (root.winfo_screenwidth()-8)
		ScreenHeight = (root.winfo_screenheight()-28)
	if os.name == 'posix':
		ScreenWidth  = root.winfo_screenwidth()
		ScreenHeight = root.winfo_screenheight()

	xpos   = 0
	ypos   = 0
	width  = ScreenWidth
	height = ScreenHeight
	root.wm_geometry("%dx%d+%d+%d" % (width,height,xpos,ypos))

	root.title("Entrys 31.01.2004-15:00")
	root["background"] = "steelblue2"

	#~~ Funktion welche beim schliessen des Hauptfensters mit
	#   der Schaltfläche X in der Titelleiste aufgerufen wird.
	root.protocol("WM_DELETE_WINDOW", ExitEntry)

	#~~ Schaltfläche für das Speichern der Eingabe
	ButtonSave = Button(root,text='Eingabe Beenden',width=20,command=ExitEntry)
	ButtonSave.pack(side=BOTTOM,pady=5)

	#~~ Schaltfläche für das verlassen der Eingabe
	ButtonExit = Button(root,text='Eingabe Speichern',width=20,command=SaveEntry)
	ButtonExit.pack(side=BOTTOM,pady=5)

	#*********************************************
	#* Welches Betriebsystem?
	#*********************************************
	#~~ Unter welchem Betriebsystem läuft Python?
	OsPlatform    = os.name

	if OsPlatform == 'nt':
		#-> Python läuft unter MS-Windows

		#~~ Verzeichnisnamen
		ENTRY_PATH       = "C:\\Entry\\"
		#~~ Namen der Datei für die Eingabedaten
		ENTRY_FILE       = 'Entry.dat'
		# me.Spacer           = "\\"

	if OsPlatform == 'posix':
		#-> Python läuft unter Linux

		#~~ Verzeichnisnamen
		ENTRY_PATH       = '/usr/Entry/'
		#~~ Namen der Datei für die Eingabedaten
		ENTRY_FILE       = 'Entry.dat'
		# me.Spacer           = "/"

	#*********************************************
	#* Verzeichnis für Eingabedaten erstellen
	#*********************************************
	#~~ Kontrolliert ob das Verzeichnis für die Eingabedaten
	#   schon vorhanden ist oder erstellt werden muss.
	try:
		os.chdir(ENTRY_PATH)
		#~~ Das Verzeichnis ist schon vorhanden
	except:
		#~~ Das Verzeichnis wird neu erstellt
		os.makedirs(ENTRY_PATH)

	#*********************************************
	#* Eingabefelder mit Bezeichnungen erstellen
	#*********************************************
	#~~ Konstante für die Anzahl der Eingabefelder
	NUM_ENTRYS = 13       # Anzahl Eingabefelder
	TOP_LEFT   = (10,10)  # Position der oberen linken Ecke
						  # des Eingabebereiches
	YGAP       = 2        # Vertikaler Zwischenraum zwischen den Feldern
	entryflag  = FALSE    # Eingabe Merker

	#~~ Deklaration der Liste für Eingabebezeichnungen
	eingabebezeichnung = []
	#~~ Fülle Liste mit Eingabebezeichnungen
	for label in range(NUM_ENTRYS):
		eingabebezeichnung.append('Bezeichnung-'+str(label+1)+':')
	#~~ Erzeuge Eingabebezeichnungen
	CreateEntryLabel(root,eingabebezeichnung)

	#~~ Deklaration der Liste für Eingabedaten
	eingabedaten       = []
	#~~ Einlesen der Eingabedaten aus der Datei in die Liste
	if ReadEntryData() == FALSE:
		#~~ Es gab Probleme beim öffen oder lesen der Datei.
		#   Fülle die Engabeliste mit Defaultwerten.
		for entry in range(NUM_ENTRYS):
			eingabedaten.append('Eingabe-'+str(entry+1))

	#~~ Deklaration der Liste für Eingabeobjekte
	eingabefelder      = []
	#~~ Erzeuge Eingabefelder
	CreateEntryField(root,eingabedaten,eingabefelder)

	root.mainloop()
Guss wuf :wink:
Take it easy Mates!
bmh1980
gelöscht
Beiträge: 60
Registriert: Montag 26. Januar 2004, 17:13
Kontaktdaten:

An die Python-Konsole habe ich gar nicht gedacht. Obwohl ich am Anfang immer mit IDLE gearbeitet habe. Ich war vorhin wohl nicht ganz da. :(

Mein Skript habe ich jetzt so abgeändert:

Code: Alles auswählen

[...]
name = self.entry1.get()
beschreibung = self.text1.get(1.0, END)
if self.text1.get(1.0, END).strip() == '':
    tkMessageBox.showerror('Fehler', 'Bitte f\xfcllen Sie alle Felder aus.')
elif '' not in [name, url, ...]:
    datei = file('/pfad/zur/datei', 'w')
    datei.write('Name: '+name)
    datei.write('URL: '+url)
    [...]
    datei.close()
else:
    tkMessageBox.showerror('Fehler', 'Bitte f\xfcllen Sie alle Felder aus.')
[...]
Ich glaube schon, dass das noch unnötig umständlich ist. Aber mit der Zeit werde ich das wohl noch einfacher hinbekommen.
Voges hat geschrieben:entries = []
entries.append(Entry(root,width=30)) # Nachname
entries.append(Entry(root,width=30)) # Vorname
entries.append(Entry(root,width=5)) # PLZ
entries.append(Entry(root,width=30)) # Ort
Was ist hier denn der Vorteil gegenüber dem einzelnen Binden an Variabeln?

@wuf: Dein Skript muss ich mir nochmal anschauen. Bin gerade beim Schreiben dieses Postings, als du gepostet hast.

Danke für eure Hilfe.
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

bmh1980 hat geschrieben:
Voges hat geschrieben:entries = []
entries.append(Entry(root,width=30)) # Nachname
entries.append(Entry(root,width=30)) # Vorname
entries.append(Entry(root,width=5)) # PLZ
entries.append(Entry(root,width=30)) # Ort
Was ist hier denn der Vorteil gegenüber dem einzelnen Binden an Variabeln?
Ganz einfach: Du kannst die bei Abfragen, die alle Entrys betreffen, diese einfach durch eine for-Schleife jagen und so alle auf einmal kontrollieren:

Code: Alles auswählen

for entry in entries:
    if entry.get().strip() == "":
        ...  #Anweisungsblock dafür...
bmh1980
gelöscht
Beiträge: 60
Registriert: Montag 26. Januar 2004, 17:13
Kontaktdaten:

Das habe ich mir schon beinahe gedacht. Die Lösung schien mir aber zu einfach. :wink:

Werde mal versuchen, dass in meinen nächsten Skripten zu benutzen. Im aktuellen möchte ich erstmal die Feinheiten noch abstimmen, bevor ich ganze Blöcke wieder abänder.

Danke!

Marcus
Voges
User
Beiträge: 564
Registriert: Dienstag 6. August 2002, 14:52
Wohnort: Region Hannover

Hallo!
Nur nur ein Hinweis zur Vervollkommnung des Programmierstils ;-): Du gehst mit dem Exception-Handling doch recht großzügig um. Beispiel:
wuf hat geschrieben:

Code: Alles auswählen

	#~~ Kontrolliert ob das Verzeichnis für die Eingabedaten
	#   schon vorhanden ist oder erstellt werden muss.
	try:
		os.chdir(ENTRY_PATH)
		#~~ Das Verzeichnis ist schon vorhanden
	except:
		#~~ Das Verzeichnis wird neu erstellt
		os.makedirs(ENTRY_PATH)
Man sollte grundsätzlich nur die Exceptions abfangen, die man auch tatsächlich erwartet. Auf 'unerwartete' Exceptions kann man eh nicht adäquat reagieren. Besser wäre also:

Code: Alles auswählen

   try:
      os.chdir(ENTRY_PATH)
      #~~ Das Verzeichnis ist schon vorhanden
   except OSError:
      #~~ Das Verzeichnis wird neu erstellt
      os.makedirs(ENTRY_PATH) 
Noch besser wäre es aber, zu ermitteln, ob wirklich die Exception ausgelöst wurde, weil es das Verzeichnis noch nicht gibt (andere Gründe gäbe es genug).

Code: Alles auswählen

   try:
      os.chdir(ENTRY_PATH)
      #~~ Das Verzeichnis ist schon vorhanden
   except OSError, err:
      import errno
      if err.errno != errno.ENOENT: raise  # unerwarteter Grund, also Exception nach oben weiterreichen
      #~~ Das Verzeichnis wird neu erstellt
      os.makedirs(ENTRY_PATH)
(Die Konstante ENOENT steht für ErrNo. 2 "No such file or directory".) os.makedirs() kann natürlich auch wieder eine Exception auslösen.
Jan
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo Jan

Besten Dank für deine Verfeinerungsvorschläge.

Ich habe mich leider noch nicht tiefgründiger
mit try: except: beschäftigt aber dies könnte der
Anfang sein.

Was heisst grosszügig in diesem Falle genau? Es ist
mir klar das bei meine Funktionen wo ich diesen try's
eingestezt habe hauptsächlich vom os abhängige Aktionen
durchgeführt werden. Das bei einem fehlschlagen der Aktion
ziemlich sicher ein os.error auslöst wird. Was passiert
wenn bei deinem 1. Vorschlag kein OSERROR ausgelöst wird
sondern ein anderer? Ist try nur auf OSERROS scharf?

Bei deinem 2.Vorschlag. Was meinst du genau mit
"Exception nach oben weiterreichen"? Wie behandels du
die nach oben gereichte Exception genau. Ich möchte zum
Beispiel eine Meldung von dieser nach oben gereichte
Exeption ausgeben und auf keine Fall eine Programm-
unterbrechung mit folgendem gezwungenen Neustart aus-
lösen.

Besten Dank
Gruss wuf :wink:
Voges
User
Beiträge: 564
Registriert: Dienstag 6. August 2002, 14:52
Wohnort: Region Hannover

Hallo wuf!
wuf hat geschrieben:ziemlich sicher ein os.error auslöst wird. Was passiert
wenn bei deinem 1. Vorschlag kein OSERROR ausgelöst wird
sondern ein anderer?
Stell' Dir vor, Du änderst auf die Schnelle was im Code und baust einen richtigen Bock und weist der Variablen ENTRY_PATH einen Integer-Wert zu. Da except: alle Exceptions abfängt, wirst Du nicht mit einer Fehlermeldung auf Deinen Flüchtigkeitsfehler hingewiesen, sondern das Programm macht so weiter, wie von Dir vorgesehen, nämlich mit makedirs(). Da scheppert es dann aber natürlich.
Bei meiner 1. Lösung schepperts dagegen sofort, denn except OSError: interessiert sich nur für OSError-Exceptions. os.chdir(4711) löst aber eine TypeError-Exception aus. Und da die try-Anweisung sich nicht zuständig fühlt für TypeErrors, wird die Exception an die nächst höhere try-Anweisung weitergeleitet, wenn es denn eine gäbe. In Deinem Script gibt es aber keine solche (was natürlich ok ist), und so bekommst Du, wenn Du das Programm von der Konsole startest eben ein
Traceback (most recent call last):
File "test.py", line 4, in ?
os.chdir(4711)
TypeError: coercing to Unicode: need string or buffer, int found
>Exit code: 1

um die Ohren gehauen.
wuf hat geschrieben:die nach oben gereichte Exception genau. Ich möchte zum
Beispiel eine Meldung von dieser nach oben gereichte
Exeption ausgeben und auf keine Fall eine Programm-
unterbrechung mit folgendem gezwungenen Neustart aus-
lösen.
Wenn Du bei anderen OSError-Arten als ENOENT keinen Script-Abbruch haben willst, darfst Du die Exception nicht hochreichen, sondern dann musst Du das Problem an Ort und Stelle angehen:

Code: Alles auswählen

   except OSError, err:
      import errno
      if err.errno == errno.ENOENT:
          os.makedirs(ENTRY_PATH)
      elif err.errno == errno.EACCES:
          # Fehlermeldung wegen fehlender Rechte
      else:
          # Fehlermeldung, dass sonstwas schief gelaufen ist
Die dt. Übersetzung des Tutoriums ist zwar schon etwas ältlich, aber im Bezug auf Exceptions hat sich da nichts Gravierendes getan:
http://starship.python.net/crew/gherman ... ode10.html
Unter http://starship.python.net/crew/gherman ... ns/tut-de/ gibt es eine aktuellere Version als PDF-Datei.
Jan
Zuletzt geändert von Voges am Samstag 31. Januar 2004, 23:58, insgesamt 1-mal geändert.
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hi Jan

Vielen Dank für deine weiteren Erläuterungen.
Du hast mich motiviert der Fehlerbehandlung
mehr Aufmerksamkeit zu widmen. Ich werden
mich nächstens mit dem Tutorial und den ein-
schlägigen Büchern befassen.

Nochmals besten Dank für deine Bemühung
Gruss wuf :wink:
Antworten