In Python gibt es keine Möglichkeit, einen try
/ except
-Block in eine einzelne Zeile zu komprimieren .
Es ist auch eine schlechte Sache, nicht zu wissen, ob eine Variable in Python vorhanden ist, wie Sie es in einigen anderen dynamischen Sprachen tun würden. Der sicherere Weg (und der vorherrschende Stil) besteht darin, alle Variablen auf etwas zu setzen. Wenn sie möglicherweise nicht festgelegt werden, setzen Sie sie None
zuerst (oder 0
oder ''
oder etwas, wenn dies zutreffender ist).
Wenn Sie tun alle die Namen assign Sie zuerst interessiert sind, haben Sie Optionen.
Die beste Option ist eine if-Anweisung.
c = None
b = [1, 2]
if c is None:
a = b
else:
a = c
Die Einzeileroption ist ein bedingter Ausdruck.
c = None
b = [1, 2]
a = c if c is not None else b
Einige Leute missbrauchen das Kurzschlussverhalten or
, um dies zu tun. Dies ist fehleranfällig, daher verwende ich es nie.
c = None
b = [1, 2]
a = c or b
Betrachten Sie den folgenden Fall:
c = []
b = [1, 2]
a = c or b
In diesem Fall sollte es a
wahrscheinlich sein , aber es liegt daran, dass es in einem booleschen Kontext falsch ist. Da es viele Werte gibt, die falsch sein können, verwende ich den Trick nicht. (Dies ist das gleiche Problem, auf das Menschen stoßen, wenn sie sagen, wann sie meinen .)[]
[1, 2]
[]
or
if foo:
if foo is not None:
try
/except
Block. Glücklicherweise sind Leitungen billig, daher sollte die 4-Zeilen-Lösung für Sie funktionieren. ;-)get
wenn Sie keine Ausnahme wünschen. Verwenden Siefilter
stattdessen.Das ist furchtbar hackisch, aber ich habe es an der Eingabeaufforderung verwendet, als ich eine Folge von Aktionen zum Debuggen schreiben wollte:
exec "try: some_problematic_thing()\nexcept: problem=sys.exc_info()" print "The problem is %s" % problem[1]
Zum größten Teil stört mich die Einschränkung, dass nur einzeiliger Versuch ausgeführt werden darf, überhaupt nicht, aber wenn ich nur experimentiere und möchte, dass readline einen ganzen Codeblock auf einmal im interaktiven Interpreter aufruft dass ich es irgendwie einstellen kann, ist dieser kleine Trick praktisch.
Für den eigentlichen Zweck, den Sie erreichen möchten, könnten Sie es versuchen
locals().get('c', b)
; Im Idealfall ist es besser, ein echtes Wörterbuch anstelle des lokalen Kontexts zu verwenden oder einfach c c None zuzuweisen, bevor Sie ausführen, was auch immer festgelegt ist oder nicht.quelle
problem[0]
zurückgeben, was diese Funktion zurückgibt?In python3 können Sie verwenden contextlib.suppress :
from contextlib import suppress d = {} with suppress(KeyError): d['foo']
quelle
Eine andere Möglichkeit besteht darin, einen Kontextmanager zu definieren:
class trialContextManager: def __enter__(self): pass def __exit__(self, *args): return True trial = trialContextManager()
Verwenden Sie dann die
with
Anweisung, um Fehler in einer einzelnen Zeile zu ignorieren:>>> with trial: a = 5 # will be executed normally >>> with trial: a = 1 / 0 # will be not executed and no exception is raised >>> print a 5
Im Falle eines Laufzeitfehlers wird keine Ausnahme ausgelöst. Es ist wie
try:
ohneexcept:
.quelle
Version von poke53280 Antwort mit begrenzten erwarteten Ausnahmen.
def try_or(func, default=None, expected_exc=(Exception,)): try: return func() except expected_exc: return default
und es könnte als verwendet werden
In [2]: try_or(lambda: 1/2, default=float('nan')) Out[2]: 0.5 In [3]: try_or(lambda: 1/0, default=float('nan'), expected_exc=(ArithmeticError,)) Out[3]: nan In [4]: try_or(lambda: "1"/0, default=float('nan'), expected_exc=(ArithmeticError,)) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) [your traceback here] TypeError: unsupported operand type(s) for /: 'str' and 'int' In [5]: try_or(lambda: "1"/0, default=float('nan'), expected_exc=(ArithmeticError, TypeError)) Out[5]: nan
quelle
parse_float = lambda x, y=exec("def f(s):\n try:\n return float(s)\n except: return None"): f(x)
Es gibt immer eine Lösung.
quelle
Verwenden Sie so etwas:
print("result:", try_or(lambda: model.objects.get(), '<n/a>'))
Wobei try_or eine von Ihnen definierte Dienstprogrammfunktion ist:
def try_or(fn, default): try: return fn() except: return default
Optional können Sie die akzeptierten Ausnahmetypen beschränken
NameError
,AttributeError
usw.quelle
Sie können es tun , indem Sie den Namespace dict Zugriff mit
vars()
,locals()
oderglobals()
, je nachdem , was für Ihre Situation am besten geeignet ist.>>> b = 'some variable' >>> a = vars().get('c', b)
quelle
Wie wäre es mit zwei Zeilen. Ist es o.k ?
>>> try: a = 3; b= 0; c = a / b ... except : print('not possible'); print('zero division error') ... not possible zero division error
quelle
Sie haben erwähnt, dass Sie Django verwenden. Wenn es für das, was Sie tun, Sinn macht, möchten Sie vielleicht Folgendes verwenden:
created
wird wahr oder falsch sein. Vielleicht hilft dir das.quelle
Wenn Sie tatsächlich Ausnahmen verwalten müssen:
(geändert von der Antwort von poke53280)
>>> def try_or(fn, exceptions: dict = {}): try: return fn() except Exception as ei: for e in ei.__class__.__mro__[:-1]: if e in exceptions: return exceptions[e]() else: raise >>> def context(): return 1 + None >>> try_or( context, {TypeError: lambda: print('TypeError exception')} ) TypeError exception >>>
Beachten Sie, dass die Ausnahme, wenn sie nicht unterstützt wird, wie erwartet ausgelöst wird:
>>> try_or( context, {ValueError: lambda: print('ValueError exception')} ) Traceback (most recent call last): File "<pyshell#57>", line 1, in <module> try_or( context, {ValueError: lambda: print('ValueError exception')} ) File "<pyshell#38>", line 3, in try_or return fn() File "<pyshell#56>", line 2, in context return 1 + None TypeError: unsupported operand type(s) for +: 'int' and 'NoneType' >>>
auch wenn
Exception
angegeben, wird es alles unten übereinstimmen.(
BaseException
ist höher, daher wird es nicht übereinstimmen)>>> try_or( context, {Exception: lambda: print('exception')} ) exception
quelle
Arbeitet an Python3, inspiriert von Walter Mundt
exec("try:some_problematic_thing()\nexcept:pass")
Für mehrere Zeilen in eine Zeile
exec("try:\n\tprint('FirstLineOk')\n\tsome_problematic_thing()\n\tprint('ThirdLineNotTriggerd')\nexcept:pass")
Ps: Exec ist unsicher für Daten, über die Sie keine Kontrolle haben.
quelle