812 Stimmen

Welche Ausnahme sollte ich auf schlechte/illegale Argumentkombinationen in Python auslösen?

Ich habe mich über die besten Praktiken für die Anzeige von ungültigen Argumentkombinationen in Python gewundert. Ich habe über ein paar Situationen kommen, wo Sie eine Funktion wie so haben:

def import_to_orm(name, save=False, recurse=False):
    """
    :param name: Name of some external entity to import.
    :param save: Save the ORM object before returning.
    :param recurse: Attempt to import associated objects as well. Because you
        need the original object to have a key to relate to, save must be
        `True` for recurse to be `True`.
    :raise BadValueError: If `recurse and not save`.
    :return: The ORM object.
    """
    pass

Das einzige Ärgernis dabei ist, dass jedes Paket seine eigene, meist leicht abweichende BadValueError . Ich weiß, dass es in Java Folgendes gibt java.lang.IllegalArgumentException -- ist es klar, dass jeder seine eigene Website erstellen wird BadValueError s in Python oder gibt es eine andere, bevorzugte Methode?

9voto

thing10 Punkte 71

Am ehesten würden Sie Folgendes verwenden ValueError ( raise ValueError() in vollem Umfang) in diesem Fall, aber es hängt von der Art des schlechten Wertes ab. Wenn Sie zum Beispiel eine Funktion entwickelt haben, die nur Zeichenketten zulässt, und der Benutzer stattdessen eine ganze Zahl eingibt, würden Sie TypeError stattdessen. Wenn ein Benutzer eine falsche Eingabe gemacht hat (d.h. sie hat den richtigen Typ, erfüllt aber bestimmte Bedingungen nicht), wird ein Value Error wäre die beste Wahl. Value Error kann auch verwendet werden, um das Programm vor anderen Ausnahmen zu schützen, z.B. könnte man eine ValueError um zu verhindern, dass die Shell eine ZeroDivisionError zum Beispiel in dieser Funktion:

def function(number):
    if not type(number) == int and not type(number) == float:
        raise TypeError("number must be an integer or float")
    if number == 5:
        raise ValueError("number must not be 5")
    else:
        return 10/(5-number)

P.S. Eine Liste der in Python eingebauten Ausnahmen finden Sie hier: https://docs.python.org/3/library/exceptions.html (Dies ist die offizielle Python-Datenbank)

0voto

BobHy Punkte 1370

Ich stimme Markus' Vorschlag zu, eine eigene Ausnahme zu erstellen, aber der Text der Ausnahme sollte klarstellen, dass das Problem in der Argumentliste und nicht in den einzelnen Argumentwerten liegt. Ich würde das vorschlagen:

class BadCallError(ValueError):
    pass

Wird verwendet, wenn Schlüsselwortargumente fehlen, die für den spezifischen Aufruf erforderlich waren, oder wenn Argumentwerte einzeln gültig sind, aber nicht miteinander übereinstimmen. ValueError wäre auch dann richtig, wenn ein bestimmtes Argument vom richtigen Typ ist, aber außerhalb des Bereichs liegt.

Sollte dies nicht eine Standardausnahme in Python sein?

Im Allgemeinen würde ich mir wünschen, dass der Python-Stil ein wenig schärfer zwischen schlechten Eingaben in eine Funktion (Fehler des Aufrufers) und schlechten Ergebnissen innerhalb der Funktion (mein Fehler) unterscheidet. Es könnte also auch einen BadArgumentError geben, um Wertfehler in Argumenten von Wertfehlern in Locals zu unterscheiden.

0 Stimmen

Ich würde die KeyError für Schlüsselwort nicht gefunden (da ein fehlendes explizites Schlüsselwort semantisch identisch ist mit einem **kwargs dict, dem dieser Schlüssel fehlt).

-2voto

cdleary Punkte 66512

Ich bin mir nicht sicher, ob ich mit der Vererbung von ValueError -- meine Interpretation der Dokumentation ist, dass ValueError ist nur soll von Builtins ausgelöst werden... davon zu erben oder es selbst auszulösen scheint nicht korrekt.

Wird ausgelöst, wenn eine integrierte Operation oder Funktion ein Argument erhält, das den den richtigen Typ, aber einen unpassenden Wert hat, und die Situation nicht durch eine präzisere Ausnahme beschrieben wie z. B. IndexError.

-- ValueError-Dokumentation

0 Stimmen

Vergleichen Sie google.com/codesearch?q=lang:python+class \+ \w Fehler(([^E] \w *|E[^x] \w )): mit google.com/codesearch?q=lang:python+class \+ \w *Error(Exception):

0 Stimmen

@dbr: Ja, ich glaube, sie meinen "(eingebaute Operation oder Funktion)", nicht "(eingebaute Operation) oder Funktion". Ich hätte gedacht, dass sie im zweiten Fall "benutzerdefiniert" sagen würden, um es zu kontrastieren.

0 Stimmen

@MizardX: Das ist interessant, ebenso wie die google.com/codesearch?q=lang%3Apython+class \+IllegalArgumentException -- sie teilen sich auf die Vererbung von ValueError, Exception und BaseException auf.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X