wholly_cow
wholly_cow

Reputation: 977

python try: except: pass; on multi line try statements

I have a block of statements in a try: except KeyError: pass block and wanted to know how I could have Python attempt to execute the code after the line that throws the exception.

For e.g

try:
  print "entering try block"
  print this_var_does_not_exists
  print "past exception"
except:
  pass

I want to try and print "past exception".

When I run the above code it only prints 'entering try block'

Upvotes: 4

Views: 27279

Answers (7)

ytzml
ytzml

Reputation: 1

I can imagine a situation, when indeed it may be useful to execute many such one-line try-excepts without a need to add try-except block each time.

Let's say that you have a dictionary d and an object o. Object has three attributes: 'a', 'b' and 'c'. Dictionary d is generated using some function generate_dict() and may have the following keys: 'x', 'y' and 'z', but you cannot be sure which of them are present in a given dictionary. You want to assign value of key 'x' to attribute 'a', 'y' to attribute 'b' etc. In such case, you have to surround each assignment with try-catch, like this:

o = Object()
d = generate_dict()
try:
    o.a = d['x']
except:
    pass
try:
    o.b = d['y']
except:
    pass

etc. You may also replace try-excepts with checking if a given key exists in the dictionary, but the problem is still there. What happens, if you have dozens of key-attribute mappings? The number of lines grows quickly.

Another way to code this is to generate two tables of attribute and key names and execute the code in a loop using exec function, like this:

o = Object()
d = generate_dict()

attributeNames = ['a', 'b', 'c']
dataDictKeys = ['x', 'y', 'z']
for (attr, key) in zip(attributeNames, dataDictKeys):
    try:
        exec("o.{attr} = d['{key}']".format(attr = attr, key = key))
    except:
        pass

While this is not a good coding practice to do such things, still this somehow may solve your problem. But use it with caution.

Upvotes: 0

dawg
dawg

Reputation: 103998

You can also use 'else' to a try/except block:

d={'a':1, 'b':2, 'd':4}

for k in 'abcd':
     try:
        print k, d[k],
     except KeyError:
        print '{} not there'.format(k)
     else:
        print 'I did it! Found {}'.format(k)   

Prints:

a 1 I did it! Found a
b 2 I did it! Found b
c c not there
d 4 I did it! Found d

In general, the full try/except/else/final set go like this:

try:
    potential_error()
except ExceptionType:
    handle_that_error_somehow()
else:                            # 'else' to the except is SUCCESS
    # There was no error
    # handle success!
    handle_success()
finally:
    # success or failure -- do this
    regardless_something_we_always_need_to_do()    

Upvotes: 5

nneonneo
nneonneo

Reputation: 179552

Python doesn't allow you to re-enter a failed block. Instead, you can make a nested try block:

try:
    print "before"
    try:
        print d['not-exist']
    except KeyError:
        pass
    print "after"
except OtherError:
    print "OtherError"

Note that you can often avoid KeyErrors using .get:

try:
    x = d['key']
except KeyError:
    x = 0

is equivalent to

x = d.get('key', 0)

In general, try to make your try blocks as short as logically possible, so you have a better chance of dealing with the errors in an appropriate, localized fashion.

Upvotes: 17

BrenBarn
BrenBarn

Reputation: 251428

You can't do it with that structure. You'd need to move the extra print out of the try block. The way a try/except block works is that if an exception is raised it jumps to the appropriate except block. There's no way to go back. If you want to continue, you need to put your code either in the except or a finally, or after the whole block. Here's one example:

try:
  print "entering try block"
  print this_var_does_not_exists
finally:
  print "past exception"

Also, don't form the dangerous habit of using bare except: clauses, especially with pass as their only content. You should catch the kinds of exceptions you can handle, and then handle them, not blindly silence all exceptions.

Upvotes: 1

SheetJS
SheetJS

Reputation: 22925

python supports finally blocks, which will be executed even if there is an exception in the try block:

try:
  print "entering try block"
  print this_var_does_not_exists
except:
  pass
finally:
  print "past exception"

Upvotes: 4

Israel Unterman
Israel Unterman

Reputation: 13510

Simply put it after the try-except block

Upvotes: 0

falsetru
falsetru

Reputation: 369244

print with literal string will not raise exception. Put try-except only in the second print statement.

print "entering try block"
try:
  print this_var_does_not_exists
except:
    pass
print "past exception"

Upvotes: 0

Related Questions