No hay forma de comprimir un bloque try
/ except
en una sola línea en Python.
Además, es malo no saber si una variable existe en Python, como lo haría en otros lenguajes dinámicos. La forma más segura (y el estilo predominante) es establecer todas las variables en algo. Si es posible que no se establezcan, configúrelos en None
primero (o 0
o ''
o algo si es más aplicable).
Si haces asignar todos los nombres que están interesados en primer lugar, usted tiene opciones.
La mejor opción es una declaración if.
c = None
b = [1, 2]
if c is None:
a = b
else:
a = c
La opción de una sola línea es una expresión condicional.
c = None
b = [1, 2]
a = c if c is not None else b
Algunas personas abusan del comportamiento de cortocircuito de or
para hacer esto. Esto es propenso a errores, por lo que nunca lo uso.
c = None
b = [1, 2]
a = c or b
Considere el siguiente caso:
c = []
b = [1, 2]
a = c or b
En este caso, a
probablemente debería serlo []
, pero es [1, 2]
porque []
es falso en un contexto booleano. Debido a que hay muchos valores que pueden ser falsos, no utilizo el or
truco. (Este es el mismo problema con el que se encuentran las personas cuando dicen lo if foo:
que quieren decir if foo is not None:
).
try
/except
. Afortunadamente, las líneas son baratas, por lo que la solución de 4 líneas debería funcionar para usted. ;-)get
si no desea una excepción. Úselo en sufilter
lugar.Esto es terriblemente hackeo, pero lo he usado en el indicador cuando quería escribir una secuencia de acciones para depurar:
exec "try: some_problematic_thing()\nexcept: problem=sys.exc_info()" print "The problem is %s" % problem[1]
En su mayor parte, no me molesta en absoluto la restricción de no probar una sola línea excepto, pero cuando solo estoy experimentando y quiero que readline recuerde una parte completa de código a la vez en el intérprete interactivo, que puedo ajustarlo de alguna manera, este pequeño truco es útil.
Para el propósito real que está tratando de lograr, puede intentarlo
locals().get('c', b)
; idealmente sería mejor usar un diccionario real en lugar del contexto local, o simplemente asignar c a Ninguno antes de ejecutar lo que sea que pueda-o-no-establecer.fuente
problem[0]
devolver lo que devuelve la función?En python3 puede usar contextlib.suppress :
from contextlib import suppress d = {} with suppress(KeyError): d['foo']
fuente
Otra forma es definir un administrador de contexto:
class trialContextManager: def __enter__(self): pass def __exit__(self, *args): return True trial = trialContextManager()
Luego use la
with
declaración para ignorar los errores en una sola línea:>>> 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
No se generará ninguna excepción en caso de un error de tiempo de ejecución. Es como
try:
sin elexcept:
.fuente
Versión de la respuesta poke53280 con limitadas excepciones esperadas.
def try_or(func, default=None, expected_exc=(Exception,)): try: return func() except expected_exc: return default
y podría usarse como
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
fuente
parse_float = lambda x, y=exec("def f(s):\n try:\n return float(s)\n except: return None"): f(x)
Siempre hay una solucion.
fuente
Usa algo como esto:
print("result:", try_or(lambda: model.objects.get(), '<n/a>'))
Donde try_or es una función de utilidad definida por usted:
def try_or(fn, default): try: return fn() except: return default
Opcionalmente se puede restringir los tipos de excepciones aceptadas a
NameError
,AttributeError
, etc.fuente
Puede hacerlo mediante el acceso al espacio de nombres utilizando dict
vars()
,locals()
oglobals()
, lo que sea más adecuado para su situación.>>> b = 'some variable' >>> a = vars().get('c', b)
fuente
¿Qué tal si usamos dos líneas? está bien ?
>>> try: a = 3; b= 0; c = a / b ... except : print('not possible'); print('zero division error') ... not possible zero division error
fuente
Mencionaste que estás usando django. Si tiene sentido para lo que está haciendo, es posible que desee utilizar:
created
será Verdadero o Falso. Quizás esto te ayude.fuente
si realmente necesita administrar las excepciones:
(modificado de la respuesta 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 >>>
tenga en cuenta que si la excepción no es compatible, se generará como se esperaba:
>>> 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' >>>
Además, si
Exception
se proporciona, coincidirá con cualquier valor que se muestra a continuación.(
BaseException
es más alto, por lo que no coincidirá)>>> try_or( context, {Exception: lambda: print('exception')} ) exception
fuente
Funciona en Python3, inspirado por Walter Mundt
exec("try:some_problematic_thing()\nexcept:pass")
Para múltiples líneas en una sola línea
exec("try:\n\tprint('FirstLineOk')\n\tsome_problematic_thing()\n\tprint('ThirdLineNotTriggerd')\nexcept:pass")
Ps: Exec no es seguro para usar en datos sobre los que no tiene control.
fuente