简体   繁体   中英

Python - nested try statements in for loop - exit out of one and process next for statement

Learning Python and grinding my gears on this one.

Have a script that connects to a list of addresses provided form a file and preforms actions on each address with pexpect. My issue is that if there is a login error, I want it to just move on to the next address after sending the exception error out to a log. What it is doing is continuing down the parent try statement to the end, which is pointless since the script couldn't connect anyway:

for ip in ips:
    try:
        try:
            #print curent address
            print "Connecting to " + ip
            #Login section
            c = pexpect.spawn('ssh -o StrictHostKeyChecking=no %s@%s' % (tacacsUser, ip))
            c.timeout = 10
            c.expect('password:')
            #Login to the device 
            c.expect('#')
        except Exception, e: #Write login errors to file
            print "Login error while connecting to " + ip
            saveLogs('LoginErrors.txt', e, 'Error connecting to ')


#send commands and such
    except Exception, e:
        print "Error occured while processing commands for " + ip
        saveLogs('ConfigErrors.txt', e, 'Error occured while processing ')

If the nested try hits the exception, I want it to move all the way back to the for loop and start with the next address.

I've been researching different exit statements from that nested except but can't seem to get the script to continue, only exit out completely.

You can use continue statement in the except part of the inner try-except block.

Example -

>>> for i in range(10):
...     try:
...             try:
...                     if i == 5:
...                             raise Exception
...             except:
...                     print("Reached 5")
...                     continue
...             print(i)
...     except:
...             print("Hmm")
...
0
1
2
3
4
Reached 5
6
7
8
9

Though I would advice that it would be better to have just one try-except block and in the except block, based on what exception is thrown you can decide what error to log/show.

If you know what the exception is going to be (and for each case it would be a different exception) , then you can have multiple excepts like -

try:
    <some logic>
except A: #handle error A
    <handle error A>
except B:
    <handle error B>

If you do not know the names of the exceptions (or they are same names) , you can use sys.exc_info() to get the information about the exception , it returns a tuple of three elements - (<type> , <value> , <Traceback>) , and you can get more information from this. (Please note it is advised not to assign traceback to a local variable in a function as it causes cyclic references.

Add a continue statement at the end of inner except block:

    for ip in ips:
        try:
            try:
                <your code>
            except:
                <your code>
                continue
        except:
            <your code>

so whenever the nested except will be reached it will start iterating over next element of the collection

Well I'm fairly certain that is how it should behave.

You are catching the exception, so nothing bad happens, and the execution proceeds as normal. I would recommend adding a continue into the child except if you want to just move on in the loop.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM