Python: try statement on one line

Is there a way in python to include try / except on the same line?

something like...

b = 'some variable' a = c | b #try statement goes here 

Where b is the declared variable, and c is not ... so c will throw an error, and a will become b ...

+60
python exception-handling
Mar 26 '10 at 16:21
source share
10 answers

It is not possible to compress a try / except block on a single line in Python.

It’s also bad to know if a variable exists in Python, like in other dynamic languages. A safer way (and prevailing style) is for all variables to be something. If they cannot be installed, first set them to None (or 0 or '' ), if more applicable.)




If you do , first assign all the names that interest you, you have options.

  • The best option is the if statement.

     c = None b = [1, 2] if c is None: a = b else: a = c 
  • The single-layer option is a conditional expression.

     c = None b = [1, 2] a = c if c is not None else b 
  • Some people abuse short-circuited or behavior to do this. This is error prone, so I never use it.

     c = None b = [1, 2] a = c or b 

    Consider the following case:

     c = [] b = [1, 2] a = c or b 

    In this case, a should probably be [] , but it is [1, 2] because [] is false in a Boolean context. Since there are many values ​​that can be false, I do not use the or trick. (This is the same problem that people face when they say if foo: when they mean if foo is not None: )

+44
Mar 26 '10 at 16:26
source share

This is terribly hacky, but I used it at the invitation when I wanted to write a sequence of actions for debugging:

 exec "try: some_problematic_thing()\nexcept: problem=sys.exc_info()" print "The problem is %s" % problem[1] 

For the most part, I am not at all bothered by the restriction of a non-single try-except line, but when I just experiment and I want readline to immediately invoke a whole piece of code into an interactive interpreter so that I can configure it as soon as possible, this little trick comes in handy.

For the actual goal you are trying to accomplish, you can try locals().get('c', b) ; ideally, it would be better to use a real dictionary instead of the local context, or just assign c to None before starting anything that might or might not install it.

+65
Nov 09 '11 at 6:26
source share

Another way is to define a context manager:

 class trialContextManager: def __enter__(self): pass def __exit__(self, *args): return True trial = trialContextManager() 

Then use the with statement to ignore errors on a single line:

 >>> 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 exception will occur in case of a runtime error. It's like try: without except:

+9
Aug 23 '17 at 13:25
source share
 parse_float = lambda x, y=exec("def f(s):\n try:\n return float(s)\n except: return None"): f(x) 

There is always a solution.

+5
Jan 22 '18 at 1:41
source share

You can do this by accessing the dict namespace using vars() , locals() or globals() , whichever is most appropriate for your situation.

 >>> b = 'some variable' >>> a = vars().get('c', b) 
+4
Mar 26 2018-10-18T00:
source share

You mentioned that you use django. If this makes sense for what you are doing, you can use:

 my_instance, created = MyModel.objects.get_or_create() 

created will be True or False. Perhaps this will help you.

+2
Mar 26 '10 at 16:44
source share

The problem is that this is actually a django model.objects.get request that I am trying to check..get returns an error if no data is found ... it does not return None (which annoys me)

Use something like this:

 print("result:", try_or(lambda: model.objects.get(), '<n/a>')) 

Where try_or is the utility function defined by you:

 def try_or(fn, default): try: return fn() except: return default 

Optionally, you can limit the allowed exception types to NameError , AttributeError , etc.

+2
01 Oct '17 at 20:51 on
source share

In python3 you can use contextlib.suppress :

 from contextlib import suppress d = {} with suppress(KeyError): d['foo'] 
+1
Aug 25 '18 at 19:17
source share

if you need to manage exceptions:
(modified from poke53280 answer)

 >>> 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 >>> 

note that if the exception is not supported, it will be raised as expected:

 >>> 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' >>> 

also, if given an Exception , it will correspond to something below.
( BaseException higher, so it will not match)

 >>> try_or( context, {Exception: lambda: print('exception')} ) exception 
0
May 08 '18 at 4:10
source share

Poke53280 response version with limited expected exceptions.

 def try_or(func, default=None, expected_exc=(Exception,)): try: return func() except expected_exc: return default 

and it can be used as

 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 
0
May 14 '19 at 19:21
source share



All Articles