Il n'y a aucun moyen de compresser un bloc try
/ except
sur une seule ligne en Python.
De plus, c'est une mauvaise chose de ne pas savoir si une variable existe en Python, comme vous le feriez dans d'autres langages dynamiques. La manière la plus sûre (et le style qui prévaut) est de définir toutes les variables sur quelque chose. S'ils ne sont pas configurés, définissez-les d' None
abord (ou 0
ou ''
ou quelque chose si c'est plus applicable.)
Si vous faites assign tous les noms qui vous intéressent d' abord, vous avez des options.
La meilleure option est une instruction if.
c = None
b = [1, 2]
if c is None:
a = b
else:
a = c
L'option one-liner est une expression conditionnelle.
c = None
b = [1, 2]
a = c if c is not None else b
Certaines personnes abusent du comportement de court-circuit de or
pour ce faire. Ceci est sujet aux erreurs, donc je ne l'utilise jamais.
c = None
b = [1, 2]
a = c or b
Prenons le cas suivant:
c = []
b = [1, 2]
a = c or b
Dans ce cas, cela devraita
probablement l' être , mais c'est parce que c'est faux dans un contexte booléen. Parce qu'il y a beaucoup de valeurs qui peuvent être fausses, je n'utilise pas l' astuce. (C'est le même problème que les gens rencontrent lorsqu'ils disent quand ils veulent dire .)[]
[1, 2]
[]
or
if foo:
if foo is not None:
try
/except
. Heureusement, les lignes sont bon marché, donc la solution à 4 lignes devrait fonctionner pour vous. ;-)get
si vous ne voulez pas d'exception. Utilisezfilter
plutôt.C'est terriblement hackish, mais je l'ai utilisé à l'invite lorsque je voulais écrire une séquence d'actions pour le débogage:
exec "try: some_problematic_thing()\nexcept: problem=sys.exc_info()" print "The problem is %s" % problem[1]
Pour la plupart, je ne suis pas du tout dérangé par la restriction no-single-line-try-except, mais quand je fais juste des expériences et que je veux que readline rappelle tout un morceau de code à la fois dans l'interpréteur interactif, donc que je peux l'ajuster d'une manière ou d'une autre, cette petite astuce est très pratique.
Pour le but réel que vous essayez d'accomplir, vous pouvez essayer
locals().get('c', b)
; idéalement, il serait préférable d'utiliser un vrai dictionnaire au lieu du contexte local, ou simplement d'assigner c à None avant d'exécuter ce que vous pouvez ou ne pouvez pas définir.la source
problem[0]
revenir ce que la fonction retourne?En python3, vous pouvez utiliser contextlib.suppress :
from contextlib import suppress d = {} with suppress(KeyError): d['foo']
la source
Une autre façon est de définir un gestionnaire de contexte:
class trialContextManager: def __enter__(self): pass def __exit__(self, *args): return True trial = trialContextManager()
Ensuite, utilisez l'
with
instruction pour ignorer les erreurs sur une seule ligne:>>> 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
Aucune exception ne sera déclenchée en cas d'erreur d'exécution. C'est comme un
try:
sans leexcept:
.la source
Version de la réponse poke53280 avec des exceptions attendues limitées.
def try_or(func, default=None, expected_exc=(Exception,)): try: return func() except expected_exc: return default
et il pourrait être utilisé comme
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
la source
parse_float = lambda x, y=exec("def f(s):\n try:\n return float(s)\n except: return None"): f(x)
Il y a toujours une solution.
la source
Utilisez quelque chose comme ceci:
print("result:", try_or(lambda: model.objects.get(), '<n/a>'))
Où try_or est une fonction utilitaire définie par vous:
def try_or(fn, default): try: return fn() except: return default
En option , vous pouvez limiter les types d'exceptions acceptées à
NameError
,AttributeError
etc.la source
Vous pouvez le faire en accédant à l'espace de noms dict en utilisant
vars()
,locals()
ouglobals()
, selon le plus approprié à votre situation.>>> b = 'some variable' >>> a = vars().get('c', b)
la source
Que diriez-vous d'utiliser deux lignes. Est-ce que c'est bon ?
>>> try: a = 3; b= 0; c = a / b ... except : print('not possible'); print('zero division error') ... not possible zero division error
la source
Vous avez mentionné que vous utilisiez django. Si cela a du sens pour ce que vous faites, vous pouvez utiliser:
created
sera vrai ou faux. Peut-être que cela vous aidera.la source
si vous devez réellement gérer les exceptions:
(modifié de la réponse de 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 >>>
notez que si l'exception n'est pas prise en charge, elle se déclenchera comme prévu:
>>> 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' >>>
aussi si
Exception
est donné, il correspondra à tout ce qui suit.(
BaseException
est plus élevé, donc il ne correspondra pas)>>> try_or( context, {Exception: lambda: print('exception')} ) exception
la source
Fonctionne sur Python3, inspiré par Walter Mundt
exec("try:some_problematic_thing()\nexcept:pass")
Pour plusieurs lignes en une seule ligne
exec("try:\n\tprint('FirstLineOk')\n\tsome_problematic_thing()\n\tprint('ThirdLineNotTriggerd')\nexcept:pass")
Ps: Exec n'est pas sûr à utiliser sur des données sur lesquelles vous n'avez pas de contrôle.
la source