SQLAlchemy中列表子集运算符<=行为异常问题求助
问题原因分析
Python中列表的<=运算符不是用来判断子集关系,而是执行字典序比较,具体规则如下:
- 若列表A是列表B的前缀且长度更短,则
A <= B返回True - 否则会逐个比较两个列表对应位置的元素,直到找到第一个不同的元素,此时会调用该元素类型的
__le__(<=)运算符进行比较 - 若所有元素都相同且长度一致,则
A <= B返回True
你前几次测试能通过属于巧合:比如filtered_orders是空列表(空列表默认<=任何列表),或者filtered_orders是all_orders的前缀,此时不需要比较元素就能返回True,不会触发错误。
而最后一次循环时,filtered_orders既不是空列表,也不是all_orders的前缀,Python会尝试比较对应位置的MoveOrder实例,但你的MoveOrder(SQLAlchemy模型类)没有实现__le__方法,因此抛出TypeError。
正确的子集判断方法
如果你要验证filtered_orders是all_orders的子集,建议用以下两种方式:
转换为集合判断(需实现哈希)
先给MoveOrder模型添加基于主键的相等性和哈希方法:class MoveOrder(Base): # ... 现有字段定义 def __eq__(self, other): if not isinstance(other, MoveOrder): return False return self.id == other.id # 假设id是模型主键 def __hash__(self): return hash(self.id)再用集合的子集方法判断:
assert set(filtered_orders).issubset(set(all_orders))遍历检查每个元素
若不想修改模型,直接遍历列表验证每个元素的存在性:assert all(order in all_orders for order in filtered_orders)注:SQLAlchemy模型默认会根据主键和会话实例判断相等性,只要
all_orders中的实例是同一会话加载的,该判断即可生效。
内容的提问来源于stack exchange,提问作者Mirage2k
相关产品推荐
相关产品推荐

