连续执行代码后出现IndexError:列表索引越界问题求助
这问题挺棘手的——刚打印出counter.ondas的长度是13,紧接着取最后一个元素就触发IndexError,还偏偏是跑了几千次才出现一次,大概率是并发修改引发的竞态条件,或者counter.ondas不是普通的Python列表,内部存在逻辑不一致的情况。给你几个具体的排查步骤:
先验证是不是并发修改的问题
如果你的代码是多线程/多进程环境,那很可能在print(len(counter.ondas))和onda = counter.ondas[-1]这两行之间,有其他线程/进程修改了counter.ondas(比如执行了pop()、clear()或者删除元素的操作),导致列表长度瞬间变成0或者小于1。你可以用锁把这两个操作包起来,看看会不会解决问题:import threading # 先给counter加个全局锁(如果是多进程的话要用multiprocessing.Lock) counter_lock = threading.Lock() with counter_lock: print(len(counter.ondas)) onda = counter.ondas[-1]如果加锁后不再报错,那基本可以确定是并发修改的问题,接下来就要去排查所有修改
counter.ondas的代码,给它们也加上对应的锁,保证操作的原子性。检查
counter.ondas的实际类型与内部逻辑
从你给出的print(counter.ondas)输出看,它看起来像是一个列表,但也有可能是自定义的序列类。你可以先打印它的类型,确认是不是普通列表:print(type(counter.ondas))如果是自定义类,那要检查它的
__len__方法和__getitem__方法是不是同步的——比如__len__返回的是缓存的数值,而实际存储的元素已经被移除了,就会出现长度和实际元素数不符的情况。验证两次长度检查的一致性
你可以在两行代码之间再做一次长度检查,看看是不是中间真的被修改了:first_len = len(counter.ondas) print(first_len) second_len = len(counter.ondas) print(second_len) if first_len != second_len: print("列表在中间被修改了!") onda = counter.ondas[-1]如果两次打印的长度不一样,那实锤是中间有其他操作修改了列表。
查看完整的
counter.ondas内容
你给出的print(counter.ondas)输出被截断了,可能实际列表里的元素有问题?可以用pprint来打印完整内容:from pprint import pprint pprint(counter.ondas)看看是不是列表里的元素其实是空的,或者
__repr__方法的输出有误导性。
内容的提问来源于stack exchange,提问作者joaoavf

