如何快速确定哪个列表导致了错误?

3
在 Python 脚本中,如果我们在单个表达式中有多个列表,例如:
a[1] = b[2] + c[3] + d[4]

或者
a[1] = b[c[d[1]]] # (This case added in EDIT)

现在,其中一个列表会抛出一个错误IndexError: List Index Out of Range ,因为索引高于列表的长度。

有没有一种使用try/except语句来改进此默认异常处理的方法,以便我们可以立即找出哪个列表引起了问题的方法?

否则,需要使用命令行调试器检查每个列表。 我知道如果有IDE可用,则此功能可能已内置于IDE中。


2
不太可能,因为Python不会告诉你哪一部分代码导致了错误。你可以尝试在except子句中逐个访问每个列表元素,这样会引发另一个错误,但这并不是可扩展的解决方案。 - Pranav Hosangadi
2
如果你关心是哪个列表引发了异常,你应该在单独的 try 语句中为每个列表编制索引,以便清楚地知道涉及哪个列表。 - chepner
刚刚阅读了即将发布的Python 3.11版本的发行说明,他们解决了这个确切的问题! :) 我已经在下面写了答案 https://dev59.com/7sLra4cB1Zd3GeqPStj-#72530238 - lifezbeautiful
3个回答

2
最简单的方法是将文本人为地分成几行。例如:
b =[1]
c = []
d = [1]

a = b[0] + \
    c[0] + \
    d[0]

Traceback (most recent call last):  
    File "/tmp/foo.py", line 7, in <module>
    c[0] + \
IndexError: list index out of range

1
很不幸,如果你在行首加上 +,比如 + c[0] \ ,这个方法就不起作用了。说实话,我也不知道为什么会这样。 - rv.kvetch
是的!我认为这可以成为一个可行的解决方法;但通常也可能存在嵌套项,例如 a[b[c[0]]] - lifezbeautiful
可以使用 \\ 相同的技巧来处理嵌套变量。 - match
@match 懂了!我会测试一下,如果可以的话就接受这个答案;不过,有没有什么工具可以自动在每个变量后面分割呢?那样会很酷,手动操作不可扩展。 - lifezbeautiful
@match,你能否在其中加入有关黑色自动格式化程序的内容。我使用了黑色代码格式化程序进行测试。black -l 1 file.py中的“1”是每行字符数,这使得你的答案具有可扩展性。我尝试编辑你的答案,但编辑队列现在已满,明天再试。 - lifezbeautiful
1
一条评论足以回答一个评论 - 您不应该添加现有的答案来回答不同问题的答案 - 最好创建一个新问题,然后自己回答它,以便其他人能够轻松找到它。 - match

1

另一个选择是使用inspect模块来查找引发错误的行号。这需要您修改加法+赋值,以使用先前定义的本地变量,例如bv = b [2],否则将其拆分成单个行,如所示。

a = [1, 2, 3]
b = [1] * 3
c = [2] * 3
d = [3] * 5

try:
    a[1] = b[2] + \
           c[3] + \
           d[4]

except IndexError:
    from inspect import trace
    var = trace()[0].code_context[0].split('=', 1)[-1].split('[', 1)[0].lstrip(' +-*')
    print(f'The variable that raised the IndexError was: {var}')

输出:

The variable that raised the IndexError was: c

有趣的事实: 以下语法,我认为是良好编码实践,但在生成信息丰富的堆栈跟踪时,实际上并不按照你的期望工作。很遗憾,我不知道为什么。

    a[1] = b[2] \
           + c[3] \
           + d[4]

0
这个问题已经得到解决,并将在 Python 3.11 解释器中提供。以下是从发布说明中复制的内容: “在打印跟踪时,解释器现在会指向导致错误的确切表达式,而不仅仅是行号。例如:”
Traceback (most recent call last):
  File "distance.py", line 11, in <module>
    print(manhattan_distance(p1, p2))
          ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "distance.py", line 6, in manhattan_distance
    return abs(point_1.x - point_2.x) + abs(point_1.y - point_2.y)
                           ^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'x'

参考资料:

发布说明PEP657


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接