Was ist eine bessere Vorgehensweise in einer benutzerdefinierten Funktion in Python: raise
eine Ausnahme oder return None
? Zum Beispiel habe ich eine Funktion, die die neueste Datei in einem Ordner findet.
def latestpdf(folder):
# list the files and sort them
try:
latest = files[-1]
except IndexError:
# Folder is empty.
return None # One possibility
raise FileNotFoundError() # Alternative
else:
return somefunc(latest) # In my case, somefunc parses the filename
Eine andere Möglichkeit besteht darin, die Ausnahme zu belassen und sie im Anrufercode zu behandeln, aber ich denke, es ist klarer, mit a FileNotFoundError
als mit a umzugehen IndexError
. Oder ist es eine schlechte Form, eine Ausnahme mit einem anderen Namen erneut auszulösen?
python
exception-handling
Parcydarks
quelle
quelle
Antworten:
Es ist wirklich eine Frage der Semantik. Was bedeutet
foo = latestpdf(d)
Mittelwert ?Ist es völlig vernünftig, dass es keine neueste Datei gibt? Dann geben Sie einfach None zurück.
Erwarten Sie, immer eine aktuelle Datei zu finden? Eine Ausnahme auslösen. Und ja, es ist in Ordnung, eine angemessenere Ausnahme erneut zu erheben.
Wenn dies nur eine allgemeine Funktion ist, die für jedes Verzeichnis gelten soll, würde ich die erstere ausführen und None zurückgeben. Wenn das Verzeichnis beispielsweise ein bestimmtes Datenverzeichnis sein soll, das die bekannten Dateien einer Anwendung enthält, würde ich eine Ausnahme auslösen.
quelle
None
.Ich würde ein paar Vorschläge machen, bevor ich Ihre Frage beantworte, da sie die Frage für Sie beantworten kann.
latestpdf
bedeutet für niemanden sehr wenig, aber wenn Sie sich Ihre Funktionlatestpdf()
ansehen, erhalten Sie das neueste PDF. Ich würde vorschlagen, dass Sie es nennengetLatestPdfFromFolder(folder)
.Sobald ich dies tat, wurde klar, was es zurückgeben sollte. Wenn es kein PDF gibt, eine Ausnahme auslösen. Aber warte dort mehr ..
for folder in folders: try: latest = getLatestPdfFromFolder(folder) results = somefuc(latest) except IOError: pass
Hoffe das hilft!
quelle
get_latest_pdf_from_folder
. In der Tat, Pep8: "Funktionsnamen sollten in Kleinbuchstaben geschrieben sein, wobei die Wörter nach Bedarf durch Unterstriche getrennt sind, um die Lesbarkeit zu verbessern."Normalerweise bevorzuge ich es, Ausnahmen intern zu behandeln (dh try / außer innerhalb der aufgerufenen Funktion, möglicherweise wird None zurückgegeben), da Python dynamisch typisiert ist. Im Allgemeinen halte ich es für einen Urteilsruf auf die eine oder andere Weise, aber in einer dynamisch typisierten Sprache gibt es kleine Faktoren, die den Ausschlag geben, die Ausnahme nicht an den Anrufer weiterzugeben:
if val is None
ist etwas einfacher alsexcept ComplicatedCustomExceptionThatHadToBeImportedFromSomeNameSpace
. Im Ernst, ich hasse es, daran denken zu müssen,from django.core.exceptions import ObjectDoesNotExist
oben in all meinen Django-Dateien zu tippen, um einen wirklich häufigen Anwendungsfall zu behandeln. Lassen Sie den Editor in einer statisch typisierten Welt dies für Sie tun.Ehrlich gesagt ist es jedoch immer ein Urteilsspruch, und die von Ihnen beschriebene Situation, in der die aufgerufene Funktion einen Fehler empfängt, dem sie nicht helfen kann, ist ein hervorragender Grund, eine sinnvolle Ausnahme erneut auszulösen. Sie haben genau die richtige Idee, aber es sei denn, Ihre Ausnahme liefert aussagekräftigere Informationen in einem Stack-Trace als
AttributeError: 'NoneType' object has no attribute 'foo'
Neun von zehn Fällen wird der Anrufer sehen, wenn Sie ein unbehandeltes None zurückgeben. Machen Sie sich keine Sorgen.
(All diese
cause
Dinge lassen mich wünschen, dass Python-Ausnahmen standardmäßig die Attribute haben, wie in Java, mit denen Sie Ausnahmen an neue Ausnahmen übergeben können, damit Sie alles neu werfen können, was Sie wollen, und niemals die ursprüngliche Ursache des Problems verlieren.)quelle
mit der Eingabe von Python 3.5 :
Beispielfunktion bei Rückgabe Keine ist:
def latestpdf(folder: str) -> Union[str, None]
und wenn eine Ausnahme ausgelöst wird, gilt Folgendes:
def latestpdf(folder: str) -> str
Option 2 scheint lesbarer und pythonischer zu sein
(+ Option zum Hinzufügen eines Kommentars zur Ausnahme wie oben angegeben.)
quelle
Union[str, None]
sollte seinOptional[str]
Im Allgemeinen würde ich sagen, dass eine Ausnahme ausgelöst werden sollte, wenn etwas Katastrophales aufgetreten ist, das nicht wiederhergestellt werden kann (dh Ihre Funktion befasst sich mit einer Internetressource, mit der keine Verbindung hergestellt werden kann), und Sie sollten None zurückgeben, wenn Ihre Funktion wirklich etwas zurückgeben sollte Es wäre jedoch nicht angebracht, etwas zurückzugeben (dh "Keine", wenn Ihre Funktion beispielsweise versucht, eine Teilzeichenfolge in einer Zeichenfolge abzugleichen).
quelle