【问题标题】:how to continue for loop after exception?异常后如何继续循环?
【发布时间】:2018-03-20 09:52:26
【问题描述】:

我有一个代码,其中我循环通过主机列表并将连接附加到连接列表,如果有连接错误,我想跳过它并继续主机列表中的下一个主机。

这是我现在拥有的:

def do_connect(self):
    """Connect to all hosts in the hosts list"""
    for host in self.hosts:
        try:
            client = paramiko.SSHClient()
            client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            client.connect(host['ip'], port=int(host['port']), username=host['user'], timeout=2)
        except:
            pass
            #client.connect(host['ip'], port=int(host['port']), username=host['user'], password=host['passwd'])

        finally:
            if paramiko.SSHException():
                pass
            else:
                self.connections.append(client)

这不能正常工作,如果连接失败,它只会一次又一次地循环同一个主机,直到它建立连接,我该如何解决这个问题?

【问题讨论】:

  • 使用continue
  • 我不明白为什么它会永远循环同一个主机?
  • 我没有看到任何再次循环同一主机的代码
  • 但确实如此,假设我在主机列表中有 host1、host2,如果无法建立与 host1 的连接,它会由于某种原因不断尝试一次又一次地循环同一个 host1。

标签: python loops exception-handling


【解决方案1】:

你自己的答案在很多方面仍然是错误的......

import logging
logger = logging.getLogger(__name__)

def do_connect(self):
    """Connect to all hosts in the hosts list"""
    for host in self.hosts:
        # this one has to go outside the try/except block
        # else `client` might not be defined.
        client = paramiko.SSHClient()
        try:
            client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            client.connect(host['ip'], port=int(host['port']), username=host['user'], timeout=2)

        # you only want to catch specific exceptions here
        except paramiko.SSHException as e:
            # this will log the full error message and traceback
            logger.exception("failed to connect to %(ip)s:%(port)s (user %(user)s)", host) 

            continue
        # here you want a `else` clause not a `finally`
        # (`finally` is _always_ executed)
        else:
            self.connections.append(client)

【讨论】:

  • 由于 2 秒超时计时器,我也收到超时错误,因此必须导入 socket.timeout 以使其正常工作,否则可以正常工作。接受的答案
【解决方案2】:

好的,开始工作了,我需要添加 Mark 提到的 Continue 以及前面的 if check inside finally 总是返回 true,因此也已修复。

这是固定的代码,它不会添加失败的连接并在此之后正常继续循环:

def do_connect(self):
    """Connect to all hosts in the hosts list"""
    for host in self.hosts:
        try:
            client = paramiko.SSHClient()
            client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            client.connect(host['ip'], port=int(host['port']), username=host['user'], timeout=2)
        except:
            continue
            #client.connect(host['ip'], port=int(host['port']), username=host['user'], password=host['passwd'])

        finally:
            if client._agent is None:
                pass
            else:
                self.connections.append(client)

【讨论】:

  • 您应该只捕获特定的异常(在您的情况下是连接错误),并始终记录它们(这样您就可以检查是否发生了错误)。此外,您还想将客户端实例放在 try/except 块之外(否则,如果它在第一台主机上失败 client 将不会被定义,并且您将在 finally 块中得到一个 NameError),然后fwiw根本不应该是 finally 块,而应该是 else 块(在没有发生异常的情况下才会执行)。
猜你喜欢
  • 2021-03-25
  • 1970-01-01
  • 1970-01-01
  • 2020-07-01
  • 2015-08-19
  • 1970-01-01
  • 2011-02-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多