2013-02-22 6 views
38

Ich habe ein Skript, wo ein Benutzer aufgefordert wird, einen Dateinamen (einer Datei, die geöffnet werden soll) einzugeben, und wenn die Datei nicht im aktuellen Verzeichnis vorhanden ist, wird der Benutzer erneut aufgefordert. Hier ist die kurze Version:Python "open()" wirft verschiedene Fehler für "Datei nicht gefunden" - wie mit beiden Ausnahmen umzugehen?

file = input("Type filename: ") 

... 
try: 
    fileContent = open(filename, "r") 
    ... 
except FileNotFoundError: 
    ... 

Als ich mein Skript auf meinem MacOS X in Python getestet 3.3x es völlig in Ordnung ist, wenn ich die falschen Dateinamen absichtlich geben (es führt die Suite unter „erwarten“).

Wenn ich jedoch meinen Code auf einem Windows-Computer in Python 3.2x ausführen wollte, erhalte ich einen Fehler, der besagt, dass "FileNotFoundError" nicht definiert ist. Also, Python 3.2 unter Windows denkt "FileNotFoundError" ist eine Variable und die Programme werden mit einem Fehler beendet.

Ich fand heraus, dass Python 3.2 unter Windows einen "IOError" auslöst, wenn der Eingabedateiname nicht gültig ist. Ich habe es auf meinem Linux-Rechner in Python 2.7 getestet und es ist auch ein IOError.

Mein Problem ist jetzt, dass der Code mit

except "FileNotFoundError": 

wird auf Windows-Python nicht ausgeführt 3.2, aber wenn ich es

except "IOError": 

es auf meinem Mac arbeiten wird sich nicht ändern nicht mehr.

Wie könnte ich es umgehen? Der einzige Weg, an den ich denken kann ist, nur except zu verwenden, was ich normalerweise nicht will.

+6

Dies ist nicht wegen Mac/Windows, es ist die * Version * von Python. Ich würde 3.2/3.3 auch auf OS X (und 3.3 auf Windows) untersuchen, die Änderungsprotokolle konsultieren und dann die Frage/den Titel entsprechend überarbeiten. –

Antwort

56

In 3.3, IOError became an alias for OSError, zu inspizieren und FileNotFoundError ist eine Unterklasse von OSError. So können Sie versuchen

except (OSError, IOError) as e: 
    ... 

Das wird ein ziemlich weites Netz geworfen, und man kann nicht davon ausgehen, dass die Ausnahme „Datei nicht gefunden“ ohne e.errno Inspektion, aber es kann Ihren Anwendungsfall abdecken.

PEP 3151 diskutiert die Gründe für die Änderung im Detail.

2

können Sie 2 Fehler zur gleichen Zeit fangen

except (FileNotFoundError, IOError):

Ich wusste nicht, dass das, was Sie fragen. Ich hoffe, es ist eine beredte Lösung dann manuell

try: 
    error_to_catch = FileNotFoundError 
except NameError: 
    error_to_catch = IOError 

except error_to_catch

cwallenpoole tut dies bedingt eloquenter in seiner Antwort (error_to_catch = getattr(__builtins__,'FileNotFoundError', IOError))

+2

Funktioniert dies, wo - * Ich bekomme einen Fehler, der besagt, dass "FileNotFoundError" nicht definiert ist. Also, Python 3.2 unter Windows denkt "FileNotFoundError" ist eine Variable und das Programm wird mit einem Fehler beendet * -? –

+0

@pst interessant Entschuldigung nicht in Betracht gezogen – dm03514

7

Dies scheint mich besser als ein einfaches except:, aber ich bin nicht sicher, ob es die beste Lösung ist:

error_to_catch = getattr(__builtins__,'FileNotFoundError', IOError) 

try: 
    f = open('.....') 
except error_to_catch: 
    print('!') 
+0

In anderen Nachrichten 'außer:' gefolgt von einem Komma ist grammatikalisch korrekt, aber immer noch sehr seltsam. – cwallenpoole

+0

Das ist auch eine sehr schöne Lösung. Ein bisschen länger als 'except (IOError, OSError):' aber deshalb spezifischer –

3

So genau nur fangen, wenn eine Datei nicht gefunden, ich mache:

import errno 
try: 
    open(filename, 'r') 
except (OSError, IOError) as e: # FileNotFoundError does not exist on Python < 3.3 
    if getattr(e, 'errno', 0) == errno.ENOENT: 
     ... # file not found 
    raise