Python解析带标记问答文本时类内answers列表返回空的问题
核心故障原因
存在两个直接导致结果异常的问题:
- 可变对象的引用传递问题:
Question_handler中的arr_ans是列表类型的可变对象。将它作为参数传入Question类时,传递的是列表的内存引用,并非列表的独立拷贝。创建完Question实例后,代码立刻执行self.arr_ans.clear()清空列表,会直接修改所有指向该内存地址的引用——也就是刚传入Question的ans属性,会被同步清空成空列表。 - 类属性与实例属性混用:
arr_ans、array、firstTime都是直接定义在类层级的类属性,并非绑定到单个实例的实例属性,所有实例会共享同一份数据,存在数据串改的隐患。
错误执行过程对应
从实际输出就能匹配上异常逻辑:
- 初始化每个
Question时,arr_ans还未被清空,因此初始化函数里的print(self.ans)能打印出完整的答案列表 - 初始化完成后立刻执行
self.arr_ans.clear(),因为Question的ans属性和arr_ans指向同一个内存地址,所以刚存进去的答案列表会被同步清空 - 后续调用
Question.get()方法时,读取到的就是已经被清空的空列表 - 重复这个流程,就会出现“初始化时能看到答案、存到对象里之后全变空”的现象。
具体修复方法
- 传递参数时做列表拷贝,切断引用关联
找到创建Question实例的代码行:
修改为传入列表的独立拷贝:self.array.append(Question(self.ques, self.desc, self.num_ans, self.cor_ans, self.arr_ans))
这样self.array.append(Question(self.ques, self.desc, self.num_ans, self.cor_ans, self.arr_ans.copy()))Question中存储的ans是独立的列表对象,后续清空handler中的arr_ans不会影响已经存到Question实例里的内容。 - 将类层级的属性迁移到实例初始化方法中,避免共享隐患
删除类层级定义的属性:
将这些属性移到class Question_handler: arr_ans = [] array = [] firstTime = True__init__方法中作为实例属性初始化:class Question_handler: def __init__(self): self.num_ans = 0 self.cor_ans = 0 self.ques = None self.desc = None self.arr_ans = [] self.array = [] self.firstTime = True - 修正文本截断的潜在问题
原代码用Qline = line[1:-1]截取行内容,遇到无换行符的最后一行时,会误把行尾最后一个字符切掉。建议修改为:
只去掉末尾的换行符,不会误删有效文本。Qline = line[1:].rstrip('\n')
修复后的预期输出
['abc', 'def', 'ghj', 'ikl'] ['Cau 1', 'Test so 1', 4, 3, ['abc', 'def', 'ghj', 'ikl']] ['100', '1000', '10000'] ['Cau 2', 'Test so 2', 3, 2, ['100', '1000', '10000']] ['A', 'B', 'C', 'D', 'E'] ['Question 3', None, 5, 5, ['A', 'B', 'C', 'D', 'E']]
内容的提问来源于stack exchange,提问作者GiBhu
相关产品推荐
相关产品推荐

