Ich möchte so etwas erreichen:
def foo():
try:
raise IOError('Stuff ')
except:
raise
def bar(arg1):
try:
foo()
except Exception as e:
e.message = e.message + 'happens at %s' % arg1
raise
bar('arg1')
Traceback...
IOError('Stuff Happens at arg1')
Aber was ich bekomme ist:
Traceback..
IOError('Stuff')
Irgendwelche Hinweise, wie dies erreicht werden kann? Wie geht das in Python 2 und 3?
message
Attribut habe ich diese SO-Frage gefunden: BaseException.message ist in Python 2.6 veraltet , was darauf hindeutet, dass die Verwendung jetzt nicht empfohlen wird (und warum sie nicht in den Dokumenten enthalten ist).Antworten:
Ich würde es so machen, so dass das Ändern des Typs
foo()
nicht auch das Ändern des Typs erfordertbar()
.Update 1
Hier ist eine geringfügige Änderung, die den ursprünglichen Traceback beibehält:
Update 2
Für Python 3.x ist der Code in meinem ersten Update syntaktisch falsch und die Idee, ein
message
Attribut zu haben,BaseException
wurde bei einer Änderung von PEP 352 am 16.05.2012 zurückgezogen (mein erstes Update wurde am 12.03.2012 veröffentlicht). . Derzeit müssen Sie in Python 3.5.2 ohnehin etwas in diese Richtung tun, um den Traceback beizubehalten und den Typ der Ausnahme in der Funktion nicht fest zu codierenbar()
. Beachten Sie auch, dass es die Zeile geben wird:in den Traceback-Meldungen angezeigt.
Update 3
Ein Kommentator fragte, ob es einen Weg gäbe, der sowohl in Python 2 als auch in Python 3 funktionieren würde. Obwohl die Antwort aufgrund der Syntaxunterschiede "Nein" zu sein scheint, gibt es einen Weg, dies zu umgehen , indem eine Hilfsfunktion wie
reraise()
imsix
Add-In verwendet wird. auf Modul. Wenn Sie die Bibliothek aus irgendeinem Grund lieber nicht verwenden möchten, finden Sie unten eine vereinfachte Standalone-Version.Beachten Sie auch, dass, da die Ausnahme innerhalb der
reraise()
Funktion erneut ausgelöst wird, diese in jedem Traceback angezeigt wird, aber das Endergebnis das ist, was Sie wollen.quelle
__str__
, erhalten Sie möglicherweise unerwünschte Ergebnisse. Beachten Sie auch, dass das zweite Argument an den Konstruktor übergeben wird, der durch das erste Argument angegeben wird, was zu einem etwas unsinnigen Ergebnis führttype(e)(type(e)(e.message)
. Drittens wird e.message zugunsten von e.args [0] abgelehnt.Falls Sie hierher gekommen sind, um nach einer Lösung für Python 3 zu suchen, heißt es im Handbuch :
Beispiel:
Was am Ende so aussieht:
Verwandeln Sie eine völlig unscheinbare
TypeError
Nachricht in eine nette Nachricht mit Hinweisen auf eine Lösung, ohne die ursprüngliche Ausnahme durcheinander zu bringen.quelle
e.args
, aber das ist ein Tupel, daher kann sie nicht geändert werden. Kopieren Sie also zuerstargs
in eine Liste, ändern Sie sie und kopieren Sie sie dann als Tupel zurück:args = list(e.args)
args[0] = 'bar'
e.args = tuple(args)
Angenommen, Sie möchten oder können foo () nicht ändern, können Sie Folgendes tun:
Dies ist in der Tat die einzige Lösung, die das Problem in Python 3 ohne eine hässliche und verwirrende Meldung "Während der Behandlung der obigen Ausnahme ist eine weitere Ausnahme aufgetreten" löst.
Falls die Zeile zum erneuten Erhöhen zur Stapelverfolgung hinzugefügt werden soll, reicht das Schreiben
raise e
anstelle von ausraise
.quelle
e.args = ('mynewstr' + e.args[0],) + e.args[1:]
Ich mag bisher nicht alle gegebenen Antworten. Sie sind imho immer noch zu ausführlich. In jeder Code- und Nachrichtenausgabe.
Alles, was ich haben möchte, ist der Stacktrace, der auf die Quellausnahme verweist, kein Ausnahmematerial dazwischen, also keine Erstellung neuer Ausnahmen, nur das Original mit allen relevanten Stack-Frame-Zuständen, die dorthin geführt haben , erneut zu erhöhen .
Steve Howard gab eine nette Antwort, die ich erweitern möchte, nein, reduzieren ... nur auf Python 3.
Das einzig Neue ist das Erweitern / Auspacken der Parameter , wodurch es klein und einfach genug für mich ist, es zu verwenden.
Versuch es:
Dies wird Ihnen geben:
Ein einfacher hübscher Druck könnte so etwas wie sein
quelle
Ein praktischer Ansatz, den ich verwendet habe, besteht darin, das Klassenattribut als Speicher für Details zu verwenden, da auf das Klassenattribut sowohl vom Klassenobjekt als auch von der Klasseninstanz aus zugegriffen werden kann:
Dann in Ihrem Code:
Und wenn Sie einen Fehler bemerken:
quelle
Im Gegensatz zu früheren Antworten funktioniert dies trotz wirklich schlechter Ausnahmen
__str__
. Es tut die Art jedoch ändern, um Faktor aus nicht hilfreich__str__
Implementierungen.Ich würde immer noch gerne eine zusätzliche Verbesserung finden, die den Typ nicht ändert.
Der ursprüngliche Traceback und Typ (Name) bleiben erhalten.
quelle
Ich werde einen Codeausschnitt bereitstellen, den ich häufig verwende, wenn ich einer Ausnahme zusätzliche Informationen hinzufügen möchte. Ich arbeite sowohl in Python 2.7 als auch in 3.6.
Der obige Code führt zu folgender Ausgabe:
Ich weiß, dass dies ein wenig von dem in der Frage angegebenen Beispiel abweicht, aber ich hoffe trotzdem, dass jemand es nützlich findet.
quelle
Sie können Ihre eigene Ausnahme definieren, die von einer anderen erbt, und einen eigenen Konstruktor erstellen, um den Wert festzulegen.
Beispielsweise:
quelle
message
ursprüngliche Ausnahme angehängt werden (könnte aber behoben werden, denke ich).Vielleicht
quelle