为何pytest中两个版本的_check_array_lengths函数报错不同?
问题解析:UnboundLocalError的成因与enumerate的作用
版本1触发错误的原因
版本1代码:
def _check_array_lengths(self, data): for i, values in data.items(): if i == 0: length = len(values) if length != len(values): raise ValueError('All values must be the same length')
核心问题是遍历对象的类型错误:data.items()返回字典的(键, 值)对,而你的测试用例中字典的键是字符串'a'和'b',并非数字0。
循环执行时,第一次迭代的i是'a',i == 0的条件永远不成立,导致length变量从未被赋值。当执行到if length != len(values):时,Python会抛出UnboundLocalError——因为length未定义就被引用了。
版本2正常运行的原因
版本2代码:
def _check_array_lengths(self, data): for i, values in enumerate(data.values()): if i == 0: length = len(values) if length != len(values): raise ValueError('All values must be the same length')
enumerate()的作用是给可迭代对象(这里是data.values(),即字典的所有值)添加从0开始递增的索引序号:
- 第一次循环时,
i为0,满足i == 0的条件,length被赋值为第一个数组的长度; - 后续循环时,
length已被定义,即使判断数组长度不一致,也能正常触发ValueError,符合测试用例的预期。
测试用例的直接影响
你的测试代码传入的是键为字符串的字典:
def test_array_length(self): with pytest.raises(ValueError): pdc.DataFrame({'a': np.array([1, 2]), 'b': np.array([1])})
这直接导致版本1里的i == 0条件永远无法触发,是错误产生的直接诱因。
内容的提问来源于stack exchange,提问作者user19
相关产品推荐
相关产品推荐

