5

So, let say I have 3 different calls called something, something1 and something2.

and right now, im calling it like

try: something something1 something2 except Keyerror as e: print e 

Note that in the above code, if something fails, something1 and something2 will not get executed and so on.

The wanted outcome is

try: something except KeyError as e: print e try: something1 except KeyError as e: print e try: something2 except KeyError as e: print e 

How can I achieve the above code without so many try except blocks.

EDIT:

So, the answer I chose as correct worked. But some of the others worked as well. I chose that because it was the simplist and I modified it a little.

Here is my solution based on the answer.

runs = [something, something1, something2] for func in runs: try: func() except Keyerror as e: print e 

6 Answers 6

11

You could try this, assuming you wrap things in functions:

for func in (something, something1, something2): try: func() except Keyerror as e: print e 
Sign up to request clarification or add additional context in comments.

Comments

6

Here's a little context manager I've used for similar situations:

from contextlib import contextmanager @contextmanager def ignoring(*exceptions): try: yield except exceptions or Exception as e: print e with ignoring(KeyError): something() # you can also put it on the same line if it's just one statement with ignoring(KeyError): something1() with ignoring(KeyError): something2() 

A Python 3 version could let you parameterize what to do when an exception occurs (the keyword-only arguments are needed here):

from contextlib import contextmanager @contextmanager def ignoring(*exceptions, action=print): try: yield except exceptions or Exception as e: callable(action) and action(e) 

Then you could pass in some function other than print (such as a logger, assumed to be a function named log) or if you don't want anything, pass in None (since it checks to see if the action is callable):

with ignoring(KeyError, action=log): something() 

6 Comments

Python 2.7 can also parameterize what to do when an exception occurs.
The way I've written it you need keyword-only args, which is a Python 3 only feature AFAIK. You could accept a single exception argument and then the caller would pass in a tuple if more than one is needed.
Keyword-only arguments are backported to Python 2.7.
@nightcracker: Are you sure? I get a SyntaxError when I try to def f(*args, x): pass in 2.7.3.
I can confirm no keyword-only args in 2.7. There was a patch for it but it was rejected. Just tried it in 2.7.5.
|
2

I would go with something like this:

def safe_do(*statements): for statement, args, kwargs in statements: try: statement(*args, **kwargs) except KeyError as e: print e # usage: safe_do( (something1, [], {}), (something2, [], {}), ) 

But if you are expecting only one element to be missing in statements than why don't you if it?

if some_key1 in some_dict1: something1 if some_key2 in some_dict2: something2 

much more readable and without any magic

Comments

1

Other possibility

def mydec(func): def dec(): try: func() except KeyError as e: print(e) return dec @mydec def f1(): print('a') @mydec def f2(): print('b') raise KeyError('Test') f1() f2() 

Comments

0

This greatly depends on whether or not you're doing similar tasks, or very different tasks. For example, if your something lines are all very similar you could do the following:

def something(my_dict): try: d = my_dict['important_key'] # Just an example, since we return d # don't know what you're really doing except KeyError as e: print e something(dict1) something(dict2) something(dict3) 

However, if your tasks are wildly different, this approach may not be applicable. To a certain degree you're asking "How do I write efficient code", and the answer to that depends on what code you're writing.

Comments

0

In python3, if you want to input a function with its args and kwargs, you can use the code below:

def safe_do(**statement): try: statement['func'](*statement['args'],**statement['kwargs']) except Exception as e: print(e) print(statement['func']) print(statement['args']) print(statement['kwargs']) def divide(a,b): print(a/b) safe_do(func=divide,args=[1,0],kwargs={}) 

In my colab notebook, I presented it.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.