You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python try块内异常未触发except分支,请求排查原因

问题描述

我正在处理欧盟议会投票结果的XML文件,发现投票结果的描述存在两种格式:纯文本形式和URL形式。其中PV-9-2022-09-12-RCV_FR.xml文件处理失败,PV-9-2022-07-06-RCV_FR.xml可正常运行。

我已添加try-except语句,但代码抛出string indices must be integers异常时,并未进入except分支处理,直接退出。需排查异常未被正确捕获的原因。

相关代码

for currentfile in f:
    mytree = ET.parse(xmlfiles + "\\" + currentfile)
    myroot = mytree.getroot()
    dixml = etree_to_dict(myroot)
    for votes in dixml['PV.RollCallVoteResults']['RollCallVote.Result']:
        try:
            title = votes['RollCallVote.Description.Text']  # 此处触发异常
            titletype = type(title)
            if titletype == dict:
                title=title['#text']
        except :
            title = votes['RollCallVote.Description.Text']['a']['#text']
        try:
            ltitle = title.lower()
        except :
            print(type(title))
        if stringtosearch in ltitle:
            print(title,currentfile)

报错栈信息

Message=string indices must be integers
  Source=...debug.py
  StackTrace:
  File "...debug.py", line 44, in <module>
    title = votes['RollCallVote.Description.Text'] 

During handling of the above exception, another exception occurred:

  File "...debug.py", line 44, in <module>
    title = votes['RollCallVote.Description.Text']
  File "...debug.py", line 49, in <module> (Current frame)
    title = votes['RollCallVote.Description.Text']['a']['#text']
问题排查与解决

核心原因分析

  1. 循环对象类型不统一:dixml['PV.RollCallVoteResults']['RollCallVote.Result']在出错的XML中是单个字典,而非列表。此时for votes in ...会遍历字典的键(字符串类型),而非预期的投票项字典。执行votes['RollCallVote.Description.Text']时,相当于对字符串使用字符串索引,直接抛出string indices must be integers异常。
  2. except分支未做防护:即使第一个异常被捕获,except分支内的代码votes['RollCallVote.Description.Text']['a']['#text']同样会因为votes是字符串而抛出相同异常,且该代码未被包裹在try块中,导致程序直接退出。
  3. 裸except风险:使用except :会捕获所有异常,但此处的异常发生在except分支内部,无法被当前try-except捕获。

修复步骤

1. 统一循环对象为列表

先判断RollCallVote.Result的类型,若为单个字典则转为列表,避免遍历字典键:

roll_call_results = dixml['PV.RollCallVoteResults']['RollCallVote.Result']
# 处理单个投票结果的情况
if not isinstance(roll_call_results, list):
    roll_call_results = [roll_call_results]
for votes in roll_call_results:
    # 后续逻辑

2. 细化异常处理与数据结构检查

明确捕获特定异常,同时在处理RollCallVote.Description.Text时先检查类型,避免索引错误:

try:
    desc_text = votes['RollCallVote.Description.Text']
    if isinstance(desc_text, dict):
        # 优先处理带URL的格式
        title = desc_text['a']['#text'] if 'a' in desc_text else desc_text['#text']
    else:
        # 纯文本格式直接赋值
        title = desc_text
except (KeyError, TypeError) as e:
    print(f"投票项解析失败: {e},文件: {currentfile}")
    continue  # 跳过当前异常项,继续处理下一个

3. 确保标题为字符串类型

在调用lower()前检查类型,避免后续报错:

if not isinstance(title, str):
    print(f"标题类型异常,文件: {currentfile},类型: {type(title)}")
    continue
ltitle = title.lower()
if stringtosearch in ltitle:
    print(title, currentfile)

修复后完整代码示例

for currentfile in f:
    mytree = ET.parse(xmlfiles + "\\" + currentfile)
    myroot = mytree.getroot()
    dixml = etree_to_dict(myroot)
    
    # 统一投票结果为列表格式
    roll_call_results = dixml['PV.RollCallVoteResults']['RollCallVote.Result']
    if not isinstance(roll_call_results, list):
        roll_call_results = [roll_call_results]
    
    for votes in roll_call_results:
        title = ""
        try:
            desc_text = votes['RollCallVote.Description.Text']
            if isinstance(desc_text, dict):
                title = desc_text['a']['#text'] if 'a' in desc_text else desc_text['#text']
            else:
                title = desc_text
        except (KeyError, TypeError) as e:
            print(f"解析投票项出错: {e},文件: {currentfile}")
            continue
        
        # 确保标题是字符串后再处理
        if not isinstance(title, str):
            print(f"标题类型异常: {type(title)},文件: {currentfile}")
            continue
        
        ltitle = title.lower()
        if stringtosearch in ltitle:
            print(title, currentfile)

内容的提问来源于stack exchange,提问作者vilmarci

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 05:20:27