Code: Alles auswählen
try:
int(value)
except ValueError or value <= 0:
raise ValueError('error')
Code: Alles auswählen
try:
int(value)
except ValueError or value <= 0:
raise ValueError('error')
Code: Alles auswählen
if int(value) <= 0:
raise ValueError('error')Ja, indem man das Fehlerhandling sinnvoll ergänzt und so Muster wie ``except SpamError: raise SpamError`` vermeidet. Mein Vorposter hat das bereits mit Code veranschaulicht. Denn letztlich geht es um die Art der Exception und nicht darum, ob jetzt der von dir erstellte Code den `ValueError` geworfen hat oder ob es fremder Code war.mutetella hat geschrieben:Gibt es eine Möglichkeit, eine exception und das Ergebnis eines Vergleichs gemeinsam zu behandeln:Code: Alles auswählen
try: int(value) except ValueError or value <= 0: raise ValueError('error')
Code: Alles auswählen
try:
value = int(value)
except ValueError:
raise ValueError('Value must be a number greater zero!')
if value <= 0:
raise ValueError('Value must be a number greater zero!')Code: Alles auswählen
try:
value = int(value)
if value <= 0:
raise ValueError()
except ValueError:
raise ValueError('Value must be a number greater zero!')Dass ich für den Fall einer nicht möglichen Umwandlung keine bezugnehmende Meldung ausgeben kann.BlackJack hat geschrieben:Was gefällt Dir an der Antwort von DasIch nicht?
Gerade das möchte ich ja. Eine Meldung ausgeben, die Bezug auf das jeweilige Argument nimmt und dem Nutzer erklärt, welcher Wert vom Programm an der Stelle erwartet wird.BlackJack hat geschrieben:Bei Deiner Lösung ersetzt Du die Meldung vom `ValueError` falls die Umwandlung fehlschlägt ...
Ich find die Meldung nicht toll weil sie das problematisch Objekt nicht beinhaltet aber ich würde mich nicht allein auf Python verlassen.BlackJack hat geschrieben:Bei Deiner Lösung ersetzt Du die Meldung vom `ValueError` falls die Umwandlung fehlschlägt durch eine schlechtere Meldung mit weniger Informationen. Einfach sein lassen.
Code: Alles auswählen
MISSING_ARGUMENT = 'Required argument \'{}\' not found.'
WRONG_TYPE_OR_VALUE = ('Argument \'{}\' must be of type \'{}\''
'with these value: {}')
class Recurrence(object):
FREQUENCIES = {'d': Daily, 'w': Weekly}
def __init__(self, frequency=None, interval=None):
if frequency is None:
raise TypeError(
MISSING_ARGUMENT.format('frequency')
)
else:
try:
self.frequency = self.FREQUENCIES[frequency[0]]
except (TypeError, KeyError):
raise TypeError(
WRONG_TYPE_OR_VALUE.format(
'frequency', 'str',
'\'d\', \'w\', \'m\' or \'y\''
)
)
try:
if interval <= 0:
raise ValueError()
self.interval = int(interval)
except ValueError:
raise TypeError(
WRONG_TYPE_OR_VALUE.format(
'interval', 'int',
'Positiv or negativ number but not zero'
)
)Was meinst Du damit? Und welchen Vorteil haben "... eigene Exception Typen ..."?DasIch hat geschrieben:... aber ich würde mich nicht allein auf Python verlassen. [...] ... am besten noch über Text hinaus Attribute mit denen man was brauchbares anfangen kann.
Mach frequency in der Funktionssignatur nicht optional, wenn es dies tatsächlich nicht ist.mutetella hat geschrieben:Ui, da hab' ich ja wieder ein Fass aufgemacht...Wie gesagt, ich möchte dem Nutzer fehlerhafte Eingaben erklären und auf mögliche Werte hinweisen:
Code: Alles auswählen
MISSING_ARGUMENT = 'Required argument \'{}\' not found.' WRONG_TYPE_OR_VALUE = ('Argument \'{}\' must be of type \'{}\'' 'with these value: {}') class Recurrence(object): FREQUENCIES = {'d': Daily, 'w': Weekly} def __init__(self, frequency=None, interval=None): if frequency is None: raise TypeError( MISSING_ARGUMENT.format('frequency') ) else: try: self.frequency = self.FREQUENCIES[frequency[0]] except (TypeError, KeyError): raise TypeError( WRONG_TYPE_OR_VALUE.format( 'frequency', 'str', '\'d\', \'w\', \'m\' or \'y\'' ) ) try: if interval <= 0: raise ValueError() self.interval = int(interval) except ValueError: raise TypeError( WRONG_TYPE_OR_VALUE.format( 'interval', 'int', 'Positiv or negativ number but not zero' ) )
Konkret für den von dir gezeigten Code haben die keine Vorteile. Grundsätzlich haben sie den Vorteil dass du Probleme genauer beschreiben kannst.Was meinst Du damit? Und welchen Vorteil haben "... eigene Exception Typen ..."?DasIch hat geschrieben:... aber ich würde mich nicht allein auf Python verlassen. [...] ... am besten noch über Text hinaus Attribute mit denen man was brauchbares anfangen kann.
Wechsel die Perspektive. Exceptions sind Teil deiner API und wenn sie auftreten möchte der Nutzer der API damit sinnvoll umgehen können. In diesem Kontext tauchen dann Fragen auf wie "Was ist schief gegangen?", "Wieso ist es schief gegangen?" oder "Wie behebe ich den Fehler?". Soweit es geht solltest du schauen dass sich diese Fragen durch die Exception beantworten lassen.Um ehrlich zu sein bin ich etwas ratlos, wie und wo ich fehlerhafte Eingaben behandeln soll:
- In den Klassen/Funktionen, in denen sie ausgelöst werden?
- Bereits beim Parsen der Argumente?
- Innerhalb eines eigenen Bereichs, in den Fehler aus den einzelnen Modulen gesendet werden?
Das kommt auf die Art des Fehlers an: Beim Parsen der Argumente kann es sich um den falschen Typen handeln, wenn z.B. ein Argument nicht als Zahl erkannt werden kann (`TypeError`). Innerhalb von Klassen oder Funktionen kann der Wertebereich des Arguments falsch sein (`ValueError)`, z.B. weil eine nicht-negative Zahl erwartet wird.mutetella hat geschrieben:Um ehrlich zu sein bin ich etwas ratlos, wie und wo ich fehlerhafte Eingaben behandeln soll:
- In den Klassen/Funktionen, in denen sie ausgelöst werden?
- Bereits beim Parsen der Argumente?
- Innerhalb eines eigenen Bereichs, in den Fehler aus den einzelnen Modulen gesendet werden?
Code: Alles auswählen
def main():
try:
args = parse_args()
main_loop(args)
except Exception as exc:
msg = 'ERROR: {}'.format(exc)
sys.exit(msg)Macht das die Behandlung des "Fehlers", `frequency` nicht definiert zu haben, nicht umständlicher?DasIch hat geschrieben:Mach frequency in der Funktionssignatur nicht optional, wenn es dies tatsächlich nicht ist.
Was meinst Du damit?DasIch hat geschrieben:... aber ich würde mich nicht allein auf Python verlassen.
Letztlich provoziert ein fehlerhaftes Argument ja an anderer Stelle einen Fehler. Der Parser müsste also Informationen haben, die ihn selbst gar nicht betreffen, um z. B. den von einer Klasse erwarteten Typ im Vorfeld zu prüfen. In welchen Fällen macht man sowas?snafu hat geschrieben:Das kommt auf die Art des Fehlers an:
Doch klar, Programmierer sollten sich weiterhelfen können...BlackJack hat geschrieben:[...] reicht dem Programmierer nicht aus?
Ja genau! Ich möchte meine Anwendung mit Fehlermeldungen versehen, die dem Benutzer so weit als möglich Hilfestellung geben.BlackJack hat geschrieben:[...] für den Benutzer zu ”beantworten”?
BlackJack hat geschrieben:Dafür sind Ausnahmen nicht gedacht.
Und wo ist das Problem? Der Parser weiß so oder so nicht, was anschließend mit dem von ihm gelieferten Ergebnis passiert. Wozu sollte er das auch wissen müssen?mutetella hat geschrieben:Der Parser müsste also Informationen haben, die ihn selbst gar nicht betreffen, um z. B. den von einer Klasse erwarteten Typ im Vorfeld zu prüfen.