General Dekorator Wrapping versuchen außer in Python?
Ich würde die Interaktion mit einer Menge von tief verschachtelten json, die ich nicht geschrieben habe, und möchte mein python-Skript mehr 'vergeben' ungültige Eingabe. Ich finde mich schriftlich beteiligt try-except-Blöcke, und würde lieber nur wickeln Sie die zweifelhafte Funktion.
Verstehe ich, dass es eine schlechte Politik zu schlucken Ausnahmen, aber ich würde eher bevorzugen, Sie werden gedruckt und analysiert später, als tatsächlich stoppen Ausführung. Es ist mehr Wert, in meinem Anwendungsfall, die weitere Ausführung über den loop als alle Schlüssel.
Hier ist, was ich jetzt mache:
try:
item['a'] = myobject.get('key').METHOD_THAT_DOESNT_EXIST()
except:
item['a'] = ''
try:
item['b'] = OBJECT_THAT_DOESNT_EXIST.get('key2')
except:
item['b'] = ''
try:
item['c'] = func1(ARGUMENT_THAT_DOESNT_EXIST)
except:
item['c'] = ''
...
try:
item['z'] = FUNCTION_THAT_DOESNT_EXIST(myobject.method())
except:
item['z'] = ''
Hier ist, was ich möchte (1):
item['a'] = f(myobject.get('key').get('subkey'))
item['b'] = f(myobject.get('key2'))
item['c'] = f(func1(myobject)
...
oder (2):
@f
def get_stuff():
item={}
item['a'] = myobject.get('key').get('subkey')
item['b'] = myobject.get('key2')
item['c'] = func1(myobject)
...
return(item)
...wo ich wickeln kann entweder die einzelnen Daten-Element (1), oder ein master-Funktion (2), in eine Funktion, schaltet der Ausführung-Stopp Ausnahmen in leere Felder, gedruckt auf stdout. Das erstere wäre eine Art von Element-wise skip - wo welche Taste ist nicht verfügbar, meldet er sich leer und bewegt sich auf - letzteres ist ein row-skip, wo Sie, wenn Sie die Felder nicht funktionieren, wird der gesamte Datensatz übersprungen.
Mein Verständnis ist, dass eine Art wrapper sollte in der Lage sein, dies zu beheben. Hier ist, was ich versucht habe, mit einem wrapper:
def f(func):
def silenceit():
try:
func(*args,**kwargs)
except:
print('Error')
return(silenceit)
Ist hier, warum es nicht funktioniert. Eine Funktion aufzurufen, die nicht existiert, ist es nicht von try-catch es Weg:
>>> f(meow())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'meow' is not defined
Bevor ich füge noch einen leeren Rückgabewert, ich mag würde, um es zu try-catch richtig. Wenn die Funktion gearbeitet hatte, dieses würde gedruckt haben "Fehler", richtig?
Ist eine wrapper-Funktion der richtige Ansatz hier?
UPDATE
Ich habe eine Menge wirklich nützliche, hilfreiche Antworten, und danke Ihnen---aber ich habe bearbeitet die Beispiele, die ich oben verwendet, um zu verdeutlichen, dass ich versuche zu fangen, mehr als verschachtelte Schlüssel-Fehler, ich bin auf der Suche speziell für eine Funktion, die wraps mit einem try-catch für...
- Wenn eine Methode nicht existiert.
- Wenn ein Objekt nicht existiert, und wird immer eine Methode aufgerufen.
- Wenn ein Objekt, das nicht existiert, aufgerufen wird, als argument an eine Funktion.
- Eine beliebige Kombination von diesen Dingen.
- Bonus, wenn eine Funktion nicht vorhanden ist.
myobject
. InformationsquelleAutor der Frage Mittenchops | 2013-03-22
Du musst angemeldet sein, um einen Kommentar abzugeben.
Könnte man eine defaultdict und der Kontext-manager-Ansatz in Raymond Hettinger ist PyCon 2013 Präsentation
InformationsquelleAutor der Antwort iruvar
Es ist sehr einfach zu erreichen mit konfigurierbaren Dekorateur.
Nur pass auf get_decorator Tupel mit Fehler-Typen, die Sie stummschalten möchten, und Standard-Wert zurück.
Ausgabe
Edit: Dank martineau ich geändert Standardwert Fehler zu Tupeln mit basic Ausnahme Fehler verhindert.
InformationsquelleAutor der Antwort Sergeev Andrew
Es gibt viele gute Antworten hier, aber ich sehe keine, die auf die Frage, ob Sie dies über Dekoratoren.
Die kurze Antwort ist "Nein", zumindest nicht ohne strukturelle änderungen an Ihrem code. Dekorateure arbeiten an der Funktion-Ebene, nicht auf einzelnen Aussagen. Deshalb, um zu verwenden, Dekorateure, Sie würde verschieben müssen, um die einzelnen Anweisungen eingerichtet werden, in seine eigene Funktion.
Aber beachten Sie, dass Sie können nicht nur setzen die Abtretung selbst innerhalb der eingerichteten Funktion. Sie brauchen, um wieder die rhs Ausdruck (der Wert, der zugewiesen wird) von der eingerichteten Funktion, dann tun die Abtretung außerhalb.
Diese in Bezug auf dein Beispiel-code ist, könnte man den code schreiben, mit dem folgenden Muster:
return_on_failure
könnte so etwas wie:InformationsquelleAutor der Antwort Nathan Davis
in Ihrem Fall, dass Sie erste, bewerten Sie den Wert der meow nennen (die nicht existieren), und dann wickeln Sie es in den Dekorateur. dies funktioniert nicht so.
erste Ausnahme wird ausgelöst, bevor es eingewickelt war, dann die Hülle ist falsch eingerückt (
silenceit
sollte nicht sich selbst zurückgeben). Möchten Sie vielleicht so etwas machen:Ausgabe:
sowieso in deinem Fall verstehe ich nicht, warum Sie nicht verwenden Sie eine einfache Methode, wie
und in den code:
Bearbeitet:
In Fall, dass Sie wollen etwas, das funktioniert in jeder beliebigen Tiefe. Sie können etwas tun:
Dass Sie nennen würde:
Und mit Ihrem code
Durch die Möglichkeit, auf einer persönlichen Sicht, die ich auch wie @cravoori Lösung mit contextmanager. Dies würde aber bedeuten, dass drei Zeilen code jedes mal:
InformationsquelleAutor der Antwort astreal
Es hängt davon ab, welche Ausnahmen Sie von uns erwarten.
Wenn Ihr nur verwenden, Fall ist
get()
Sie tun konnte,Für die anderen Fälle, Ihre decorator-Ansatz könnte nützlich sein, aber nicht in der Art und Weise Sie es tun.
Ich werde versuchen, Ihnen zu zeigen:
Trotzdem
f(some_undefined_function())
wird nicht funktionieren, weila)
f()
ist noch nicht aktiv an der executon Zeit undb) es verwendet wird, falsch. Der richtige Weg wäre, um wickeln Sie die Funktion und rufen Sie dann:
f(function_to_wrap)()
.Einer "Schicht von lambda" würde hier helfen:
umschließt eine lambda-Funktion, die wiederum ruft eine nicht vorhandene Funktion. Aufruf
wrapped_f()
führt zum Aufruf der wrapper die Aufrufe der lambda, das versucht, zu rufenmy_function()
. Wenn diese nicht vorhanden ist, wird der lambda-Ausdruck eine Ausnahme auslöst, die gefangen durch den wrapper.Dies funktioniert, weil der name
my_function
wird nicht ausgeführt, zum Zeitpunkt der lambda-Ausdruck definiert wird, aber wenn es ausgeführt wird. Und diese Ausführung ist geschützt und umschlossen wird von der Funktionf()
dann. Also die Ausnahme tritt innerhalb der lambda und weitergegeben wird, um die Verpackung Funktion der Dekorator, welche Griffe Sie anmutig.Dieser Richtung innerhalb der lambda-Funktion funktioniert nicht, wenn Sie versuchen, ersetzen Sie die lambda-Funktion mit einem wrapper wie
gefolgt von einem
weil hier die Namensauflösung ist "zurück an der Oberfläche":
my_function
nicht aufgelöst werden, und dies geschieht, bevorg()
oder sogarf()
genannt werden. So funktioniert es nicht.Und wenn Sie versuchen, etwas zu tun, wie
kann es nicht so gut funktionieren, wenn Sie keine
x
, weilg()
schütztprint
, nichtx
.Wenn Sie schützen möchten
x
hier, Sie haben zu tun,weil der wrapper zur Verfügung gestellt von
f()
fordert, dass die lambda-Funktion, die eine Ausnahme auslöst, die dann zum schweigen gebracht.InformationsquelleAutor der Antwort glglgl
Da Sie den Umgang mit vielen gebrochenen code, kann es sein, entschuldbar zu verwenden
eval
in diesem Fall.Dann wickeln Sie alle Ihre möglicherweise gebrochen Aussagen:
InformationsquelleAutor der Antwort Addison
Warum nicht einfach Zyklus?
Oder wenn Sie wollen schreiben einen kleinen Helfer:
Sie können auch kombinieren Sie die beiden Lösungen, wenn Sie ein paar Orte, wo Sie brauchen, um Wert und Helfer Funktion wäre sinnvoller.
Nicht sicher, ob Sie tatsächlich benötigen einen Dekorator für Ihr problem.
InformationsquelleAutor der Antwort simplylizz