Python:如何简化继承list的Packet类比较方法,消除代码冗余?
解决方案:动态生成比较方法避免代码重复
要实现和list行为一致但支持与int比较的Packet类,核心思路是把重复的类型判断和转换逻辑抽离,通过动态生成的方式创建6个正向比较方法和6个反向比较方法,彻底消除代码重复。
方法一:类装饰器实现(推荐,代码更整洁)
用装饰器封装比较方法的生成逻辑,让Packet类的定义更简洁:
def enable_int_comparison(cls): # 生成正向比较方法:处理 Packet vs int def create_comparison(op_name): def method(self, other): if isinstance(other, int): other = cls([other]) return getattr(super(cls, self), op_name)(other) return method # 生成反向比较方法:处理 int vs Packet def create_reverse_comparison(op_name): def method(self, other): if isinstance(other, int): other = cls([other]) # __rlt__ 对应调用 other.__lt__(self),等价于 int < Packet → Packet([int]) < Packet return getattr(other, op_name[2:])(self) return method # 批量添加正向比较方法 for op in ('__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__'): setattr(cls, op, create_comparison(op)) # 批量添加反向比较方法 for op in ('__rlt__', '__rle__', '__req__', '__rne__', '__rgt__', '__rge__'): setattr(cls, op, create_reverse_comparison(op)) return cls @enable_int_comparison class Packet(list): pass
方法二:直接在类定义后动态添加方法
如果不想用装饰器,也可以在类定义完成后,通过循环批量设置方法:
class Packet(list): pass # 生成正向比较方法 def create_comparison(op_name): def method(self, other): if isinstance(other, int): other = Packet([other]) return getattr(super(), op_name)(other) return method # 生成反向比较方法 def create_reverse_comparison(op_name): def method(self, other): if isinstance(other, int): other = Packet([other]) return getattr(other, op_name[2:])(self) return method # 批量绑定正向方法 for op in ('__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__'): setattr(Packet, op, create_comparison(op)) # 批量绑定反向方法 for op in ('__rlt__', '__rle__', '__req__', '__rne__', '__rgt__', '__rge__'): setattr(Packet, op, create_reverse_comparison(op))
验证功能
两种实现的效果完全一致,测试示例:
p = Packet([1, 2]) # 正向比较:Packet vs int print(p < 3) # 等价于 Packet([1,2]) < Packet([3]) → True print(p == 2) # 等价于 Packet([1,2]) == Packet([2]) → False print(p >= 1) # 等价于 Packet([1,2]) >= Packet([1]) → True # 反向比较:int vs Packet print(3 > p) # 等价于 Packet([3]) > Packet([1,2]) → True print(2 == p) # 等价于 Packet([2]) == Packet([1,2]) → False print(1 <= p) # 等价于 Packet([1]) <= Packet([1,2]) → True
核心逻辑说明
- 类型统一:只要比较对象是
int,就自动转换成Packet([int]),确保后续调用list原生的比较逻辑。 - 批量生成:通过循环遍历所有比较方法名,用工厂函数生成对应方法,避免重复编写6次几乎相同的代码。
- 反向兼容:处理
int在比较运算符左侧的场景(比如5 > Packet([3])),确保所有比较方向都符合需求。
内容的提问来源于stack exchange,提问作者schtandard
相关产品推荐
相关产品推荐

