Fehler in Funktion mit pickle und os.path.isfile()

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
Benutzeravatar
C4S3
User
Beiträge: 292
Registriert: Donnerstag 21. September 2006, 10:07
Wohnort: Oberösterreich

Hallo beisammen!

Tut mir leid, wenn die Fehlerbeschreibung etwas vage ist, aber ich kanns echt nicht anders sagen.

Also, ich bekomme bei einem Script folgenden Fehler, denn ich nicht so recht zu deuten vermag:
Traceback (most recent call last):
File "/home/case/codes/adrA_1.py", line 20, in ?
Startup()
File "/home/case/codes/adrA_1.py", line 12, in Startup
liste = pickle.load(adrFile)
File "/usr/lib/python2.4/pickle.py", line 1390, in load
return Unpickler(file).load()
File "/usr/lib/python2.4/pickle.py", line 871, in load
key = read(1)
IOError: [Errno 9] Bad file descriptor
OK, Zeile 20 ist der Aufruf einer Funktion udn Zeile 12 ist in der Funktion.
Hier noch die Funktion - beim Starten des Programmes soll gecheckt werden, ob die Datei schon existiert, wenn nicht wird sie angelegt, wenn ja, mittels pickle in eine Liste übertragen (so sollte es halt sein):

Code: Alles auswählen

import os, sys, pickle

# open existing file or create new
def Startup():
	adrFileName = "adRSA.pbf"
	adrFile = file(adrFileName, "w")
	qApp = False
	liste = []
	
	if os.path.isfile(adrFileName):
		liste = pickle.load(adrFile)
	else:
		pickle.dump(liste, adrFile, True)
Naja, irgendwie steh ich jetzt an, kann aber meine Frage nicht so recht formulieren. Ein "was mache ich falsch" scheint nicht das richtige zu sein. Aber, was mich beschäftigt: sind variablen innerhalb einer Funktion local oder immer global, oder wie ist das bei Python?
Gruß!
murph
User
Beiträge: 622
Registriert: Freitag 14. April 2006, 19:23
Kontaktdaten:

du kannst mit "w" nicht lesen.
dafür musst du "w+" oder noch besser "w+b nehmen.
zum laden des dumps liest der ja natürlich...

innerhalb einer funktion werden alle immutablen variablen als nicht bekannt gesetzt, außer man benutzt global. falls außerhalb der funktion diese gesetzt wurde, ist sie in der funktion unbekannt.
wenn es mutabel ist (liste, dict), dann ist es in der funktion bekannt, wenn es außerhalb gesetzt wurde. dieses braucht kein global.
http://www.cs.unm.edu/~dlchao/flake/doom/
Benutzeravatar
C4S3
User
Beiträge: 292
Registriert: Donnerstag 21. September 2006, 10:07
Wohnort: Oberösterreich

Danke. Wieder was dazugelernt. Also global muss innerhalb einer Funktion deklariert werden..
Btw: mich nimmts Wunder, dass man nicht global adrFileName = "adRSA" schreiben kann. Da bekomme ich auch Fehler.

Hab die Funktion jetzt folgendermaßen umgeschrieben:

Code: Alles auswählen

def Startup():
	global adrFileName
	adrFileName = "adRSA.pbf"
	global adrFile
	adrFile = file(adrFileName, "w+")
	global qApp
	qApp = False
	liste = []
	
	if os.path.isfile(adrFileName):
		liste = pickle.load(adrFile)
	else:
		pickle.dump(liste, adrFile, True)
Main Menu
=========
Traceback (most recent call last):
File "/home/peter/codes/adrA_1.py", line 24, in ?
Startup()
File "/home/peter/codes/adrA_1.py", line 16, in Startup
liste = pickle.load(adrFile)
File "/usr/lib/python2.4/pickle.py", line 1390, in load
return Unpickler(file).load()
File "/usr/lib/python2.4/pickle.py", line 872, in load
dispatch[key](self)
File "/usr/lib/python2.4/pickle.py", line 894, in load_eof
raise EOFError
EOFError
EOF --> End of File? Sieht aus, als käme pickle da mit irgendetwas nicht zurecht. Und der Grund steckt in der Funktion. Aber wo und warum!?
Gruß!
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Igitt, globals!

Das Problem ist ganz einfach zu erklären: pickle kann file-Objekte nicht serialisieren.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
C4S3
User
Beiträge: 292
Registriert: Donnerstag 21. September 2006, 10:07
Wohnort: Oberösterreich

Das Problem ist ganz einfach zu erklären: pickle kann file-Objekte nicht serialisieren
??
Ganz ehrlich gesagt, stehe ich jetzt vollkommen auf der Leitung.

Ich habe doch schon erfolgreich eine Liste, die voll mit Objekten war, mittels pickle.dump() gespeichert und auch wieder mit pickle.load() ausgelesen.

Ich möchte ja hier, beim starten des Sripts nicht mehr tun, als zu schauen, ob die Datei existiert und wenn ja, in die Liste zurückladen und wenn nicht, gleich die Datei erstellen.
:K [/code]
Gruß!
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

C4S3 hat geschrieben:
Das Problem ist ganz einfach zu erklären: pickle kann file-Objekte nicht serialisieren
??
Ganz ehrlich gesagt, stehe ich jetzt vollkommen auf der Leitung.
Verständlich - ich habe da irgendeinen Quark geschrieben - sorry dafür.

achromatic.PickleBackend.load() macht glaube ich genau das, was du meisnt: es versucht einen dump zu laden und wenn das nicht klappt, dann erstellt es eine leere Einstellungsvariable. In deinem Fall würdest du an der Stelle einen Dump anlegen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
C4S3
User
Beiträge: 292
Registriert: Donnerstag 21. September 2006, 10:07
Wohnort: Oberösterreich

Dankeschön!
:D

Das hilft in zweierlei Hinsicht. Vor allem deshalb, weil ich jetzt nicht mehr befürchten muss, dass das bisherige Lesen und Lernen umsonst war.
Gruß!
BlackJack

Als erstes vergiss was murph über ``global`` geschrieben hat. Das ist mal wieder totaler Müll und geht mir langsam echt auf die Nerven. Wenn man keine Ahnung hat, dann kann man auch die Klappe halten statt Leute zu verwirren. ``global`` bezieht sich auf Namen und Namen haben in Python keinen Typ, d.h. da kann auch kein Unterschied zwischen mutable und immutable Objekten gemacht werden, das funktioniert immer gleich.

Wenn man innerhalb einer Funktion etwas an einen Namen bindet, egal wo, dann ist dieser Name lokal zur Funktion. Ausser wenn man ihn in der Funktion mit ``global`` als (modul)global deklariert. Das hat aber mit dem Problem hier überhaupt gar nichts zu tun.
C4S3 hat geschrieben:Hier noch die Funktion - beim Starten des Programmes soll gecheckt werden, ob die Datei schon existiert, wenn nicht wird sie angelegt, wenn ja, mittels pickle in eine Liste übertragen (so sollte es halt sein):

Code: Alles auswählen

import os, sys, pickle

# open existing file or create new
def Startup():
	adrFileName = "adRSA.pbf"
	adrFile = file(adrFileName, "w")
	qApp = False
	liste = []
	
	if os.path.isfile(adrFileName):
		liste = pickle.load(adrFile)
	else:
		pickle.dump(liste, adrFile, True)
Gehen wir das mal durch. Du öffnest eine Datei zum schreiben. Egal ob die Datei existierte oder nicht, jetzt gibt es sie! Und sie ist leer, sprich 0 Bytes lang. Auch falls sie vorher schon existierte und Inhalt hatte -- der ist jetzt weg!

Beim ``if`` wird immer der erste Zweig ausgeführt weil Du die Datei erzeugt hast, falls es sie vorher noch nicht gab. Und dann versuchst Du aus der zum schreiben geöffneten und völlig leeren Datei etwas zu laden. Dat jeht nich.

Am besten Du versuchst einfach die pickle-Datei zu laden und fängst einen eventuellen Dateifehler mit ``try``/``except`` ab und erzeugst die Datei falls der ``except`` Fall eintritt.

Und pickle-Dateien solltest Du immer im Binärmodus öffnen.
Benutzeravatar
C4S3
User
Beiträge: 292
Registriert: Donnerstag 21. September 2006, 10:07
Wohnort: Oberösterreich

OK, ich sehe schon.
Auch wenn Python eine "leicht zu erlernende Sprache ist", kommen da teilweise Dinge auf mich zu, von denen ich noch nie gehört habe. *Wikipedia_nach_mutable_frag*
Du öffnest eine Datei zum schreiben. Egal ob die Datei existierte oder nicht, jetzt gibt es sie! Und sie ist leer, sprich 0 Bytes lang. Auch falls sie vorher schon existierte und Inhalt hatte -- der ist jetzt weg!
Ah, da könnte der Wurm liegen.

Danke erst mal - ich werde meine Konzept einfach noch mal überdenken!
Gruß!
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

C4S3 hat geschrieben:OK, ich sehe schon.
Auch wenn Python eine "leicht zu erlernende Sprache ist", kommen da teilweise Dinge auf mich zu, von denen ich noch nie gehört habe. *Wikipedia_nach_mutable_frag*
Wie BlackJack sagte, mutable/immutable hat mit deinem Problem nichts zu tun. Hier aber eine sehr schoene Erklaerung: http://www.python-forum.de/post-37245.html#37245
murph
User
Beiträge: 622
Registriert: Freitag 14. April 2006, 19:23
Kontaktdaten:

sorry, war dann wohl ein schönes ritual von mir...
werde mich in solchen fällen dann mal zurückhalten.
http://www.cs.unm.edu/~dlchao/flake/doom/
Antworten