【问题标题】:Python - Continuing after exception at the point of exceptionPython - 在异常点出现异常后继续
【发布时间】:2012-02-08 18:53:42
【问题描述】:

我正在尝试从 xml 文件中提取数据。我的代码示例如下:

    from xml.dom import minidom
    dom = minidom.parse("algorithms.xml")
    ...
       parameter = dom.getElementsByTagName("Parameters")[0]
       # loop over parameters
       try:
            while True:
                parameter_id = parameter.getElementsByTagName("Parameter")[m].getAttribute("Id")
                parameter_name = parameter.getElementsByTagName("Name")[m].lastChild.data
                ...
                parameter_default = parameter.getElementsByTagName("Default")[m].lastChild.data
                print parameter_id
                print parameter_default
                m = m+1
        except IndexError:
            #reached end of available parameters
            pass
        #except AttributeError:
            #parameter doesn't exist
            #?

如果每个参数的所有元素都存在,则代码运行正确。不幸的是,我提供的数据中经常缺少条目,从而引发 AttributeError 异常。如果我只是传递该错误,那么任何确实存在但在循环中稍后检索的元素都会被跳过,而不是发生异常时,这是我不想要的。如果引发此特定异常,我需要一些方法来继续代码停止的地方并跳到下一行代码。

我能想到的解决这个问题的唯一方法是重写 minidom 的类方法并在那里捕获异常,但这似乎太混乱了,而且工作量太大,无法处理应该是一个非常简单和常见的问题.有没有更简单的方法来处理我错过的这个问题?

【问题讨论】:

  • AttributeError 不是 minidom 异常...它指的是尝试访问不存在的 Python 对象属性。如果该属性不存在,Minidom 的getAttribute() 方法将返回一个空字符串。请提供示例堆栈跟踪并确定代码中引发异常的语句。

标签: python python-3.x


【解决方案1】:

为什么不将那部分抽象出来,而不是“每个语句都有一个单独的 try-except 块”?

def getParam(p, tagName, index, post=None):
    post = post or lambda i: i
    try:
        return post(p.getElementsByTagName(tagname)[index])
    except AttributeError:
        print "informative message"
    return None # will happen anyway, but why not be explicit?

然后在循环中你可以有这样的东西:

parameter_id = getParam(parameter, "Parameter", m, lambda x: x.getAttribute("Id"))
parameter_name = getParam(parameter, "Name", m, lambda x: x.lastChild.data)
...

【讨论】:

  • 空字符串没有getAttributelastChild 属性,所以AttributeError 仍然可以在此处和原始问题中提出。
  • 在该级别捕获 AttributeError 是否会阻止 IndexError 正确触发和退出循环?
  • No AttributeError 与 IndexError 不同
【解决方案2】:

我认为您的问题有两个部分。首先,您希望循环在第一个 AttributeError 之后继续。您可以通过将 try 和 except 移动到循环中来做到这一点。

类似这样的:

try:
    while True:
        try:
            parameter_id = parameter.getElementsByTagName("Parameter")[m].getAttribute("Id")
            parameter_name = parameter.getElementsByTagName("Name")[m].lastChild.data
            ...
            parameter_default = parameter.getElementsByTagName("Default")[m].lastChild.data
            print parameter_id
            print parameter_default
            m = m+1
        except AttributeError:
            print "parameter doesn't exist"
        #?
except IndexError:
    #reached end of available parameters
    pass

第二部分更棘手。但另一个答案很好地解决了这个问题。

【讨论】:

  • 简单地将其移入循环不会改变问题(并且不在循环外处理 IndexError 会导致无限循环)。我可以为要检索的每个元素设置一个单独的 try-except 块,但对我来说,这似乎是一种可怕的编码方式,并且需要太多的努力。
  • 你的休息时间在哪里/
  • @thavan,我有一个缩进错误。我不熟悉他的代码库,但从循环中逃脱是通过 IndexError 就像他的原始代码一样。
  • 这似乎不正确;如果parameter_name 无法读取但parameter_default 本来可以读取,则在处理异常后我们没有它们中的任何一个,因为我们跳过了将读取parameter_default 的调用。提问者希望能够阅读所有可以阅读的内容,而不管之前的阅读是否失败。将内容存储在 dict 中只是让您知道在失败之前读取了哪些内容。
  • @thavan,你在问谁关于无限循环?我不明白你的意思。
猜你喜欢
  • 2021-06-20
  • 2021-06-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-13
  • 2018-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多