Python中Matrix类__eq__方法pytest测试失败问题排查
问题分析与解决方案
核心问题出在m1的初始化方式错误,导致它的内部数据结构和m2完全不一致,进而让__eq__方法返回False。我们一步步拆解:
1. 初始化方式的差异导致数据结构不同
你的Matrix类__init__用了*rows可变参数,这意味着它接受多个行参数,每个行是一个列表:
m2 = Matrix([1,2,3],[4,5,6])是正确的:rows会被解析为([1,2,3], [4,5,6]),所以self._rows = [[1,2,3], [4,5,6]],这是一个两行三列的矩阵。- 但
m1 = Matrix([[1,2,3],[4,5,6]])是错误的:你只传了一个参数——一个包含两个子列表的嵌套列表,此时rows被解析为([[1,2,3],[4,5,6]],),所以self._rows = [[[1,2,3],[4,5,6]]],这是一个只有一行的矩阵,这行的内容是那个嵌套列表。
这两个矩阵的内部存储完全不同,__eq__自然会判定它们不相等。
2. 你的__eq__方法还有其他潜在问题
除了初始化的问题,原__eq__的实现也不够严谨:
- 缺少
itertools.zip_longest的导入(如果没导入会直接报错); - 用
zip_longest的话,当两个矩阵行数不同时会补None,但直接比较x == y虽然能区分,但不如先检查行数是否一致清晰; isinstance(self, other.__class__)的写法不符合Python惯例,应该优先判断对方是否是当前类的实例。
修正后的代码
首先修正Matrix类的实现
from itertools import zip_longest class Matrix: def __init__(self, *rows): if not rows: raise ValueError("Matrix cannot be empty") row_length = len(rows[0]) for row in rows: if len(row) != row_length: raise SystemError("Rows do not have equal length") self._rows = list(rows) # 用list(rows)比[*rows]更直观 def __eq__(self, other): # 先判断对方是否是Matrix实例 if not isinstance(other, Matrix): return False # 行数不同直接不相等 if len(self._rows) != len(other._rows): return False # 逐行比较每一个元素 for self_row, other_row in zip(self._rows, other._rows): if self_row != other_row: return False return True
然后修正测试用例的初始化方式
def test_eq(): m1 = Matrix([1,2,3], [4,5,6]) # 改成和m2一致的多参数传入 m2 = Matrix([1,2,3], [4,5,6]) m3 = Matrix([1,2,3], [5,4,6]) assert m1 == m2 assert m2 == m1 assert m2 != m3
为什么之前修改后仍有问题?
你提到已根据他人回答修改但仍报错,大概率是没有修正测试用例里m1的初始化方式,或者__eq__的逻辑仍存在疏漏(比如没处理行数不一致的情况)。按照上面的代码调整后,测试应该能正常通过。
内容的提问来源于stack exchange,提问作者Alvaro Pedraza
相关产品推荐
相关产品推荐

