Python中重声明同结构namedtuple无法比较类型的解决方法问询
根本原因
collections.namedtuple 每次调用都会生成全新的独立类对象,即使两次声明的类名、字段列表完全一致,生成的两个类的内存地址也不相同,因此直接用type(a) == type(b)或者isinstance判断都会返回False,这是Python类定义的原生特性,不是运行异常。
解决方案
以下方案均不需要将类型转为字符串,可直接判定语义相等:
方案1:对比namedtuple类的核心属性
标准namedtuple生成的类自带三个可唯一标识其语义的属性,三者同时匹配即可判定为语义相同的namedtuple类型:
__name__:声明时传入的类名_fields:类的字段元组__module__:类所属的模块名(可避免不同模块下同名同字段类的误判)
你可以封装一个通用判断函数:
def is_namedtuple_semantic_equal(type1: type, type2: type) -> bool: # 先校验两个类型都是namedtuple生成的类 if not (hasattr(type1, '_fields') and hasattr(type2, '_fields')): return False return ( type1.__name__ == type2.__name__ and type1._fields == type2._fields and type1.__module__ == type2.__module__ )
使用时直接调用即可:
assert is_namedtuple_semantic_equal(type(a), type(b))
方案2:实例级别的鸭子类型判断(更适配差分引擎场景)
如果你开发的差分引擎本身需要同时校验结构和值,可以直接对实例做判断,不需要先提取类型:
def is_same_namedtuple_instance(obj1, obj2) -> bool: # 先校验两个都是tuple实例(namedtuple本身继承自tuple) if not (isinstance(obj1, tuple) and isinstance(obj2, tuple)): return False type1 = type(obj1) type2 = type(obj2) # 校验都是namedtuple类的实例,且字段列表一致 if not (hasattr(type1, '_fields') and hasattr(type2, '_fields') and type1._fields == type2._fields): return False # 最后校验值相等 return obj1 == obj2
该方案容错性更高,只要实例的结构、字段、值完全一致,就会判定为无差异,不需要严格的类对象相等,非常适合做结构差分的场景。
内容的提问来源于stack exchange,提问作者Drakes
相关产品推荐
相关产品推荐

