如何在Python对象自定义属性上实现类SQL的匹配器查询?
实现自定义嵌套属性匹配器函数
核心思路
要实现需求中的匹配逻辑,我们拆分三个核心部分:
- 嵌套属性提取:统一处理字典和类实例的嵌套属性访问
- 基础匹配器:实现
exist、greater_than等基础判断逻辑 - 逻辑组合器:实现
or、and、not等逻辑组合,支持多个匹配器的组合使用
完整代码实现
1. 嵌套属性提取工具函数
实现通用工具函数,从字典或类实例中按路径提取嵌套属性:
def get_nested_value(data, path): keys = path.split('.') current = data for key in keys: if isinstance(current, dict): if key not in current: return None current = current[key] else: if not hasattr(current, key): return None current = getattr(current, key) return current
2. 基础匹配器实现
每个基础匹配器返回一个可调用的判断函数,接收数据后返回布尔值:
def exist(path): """检查指定路径的属性是否存在""" def matcher(data): return get_nested_value(data, path) is not None return matcher def greater_than(path, value): """检查指定路径的属性值大于给定值(属性需存在)""" def matcher(data): val = get_nested_value(data, path) return val is not None and val > value return matcher # 可扩展其他基础匹配器,比如相等、小于等 def equal_to(path, value): def matcher(data): return get_nested_value(data, path) == value return matcher
3. 逻辑组合器实现
由于Python中or、and是关键字,用or_、and_命名组合器实现逻辑组合:
def or_(*matchers): """逻辑或:任意一个匹配器匹配成功则返回True""" def matcher(data): return any(m(data) for m in matchers) return matcher def and_(*matchers): """逻辑与:所有匹配器匹配成功才返回True""" def matcher(data): return all(m(data) for m in matchers) return matcher def not_(matcher): """逻辑非:反转匹配器的结果""" def negated_matcher(data): return not matcher(data) return negated_matcher
4. 主函数实现
主函数直接调用传入的匹配器即可:
def myfunction(data, matcher): return matcher(data)
测试示例
按照需求示例测试(修正拼写错误后):
# 构建匹配规则:要么property.sub_property存在且大于49,要么该属性不存在 matcher = or_(greater_than("property.sub_property", 49), not_(exist("property.sub_property"))) # 测试数据无目标属性,返回True result = myfunction({"some_object": 1}, matcher) print(result) # 输出:True
扩展测试(类实例场景)
支持类实例的嵌套属性匹配:
class TestObj: def __init__(self): self.property = TestSubObj() class TestSubObj: def __init__(self): self.sub_property = 50 obj = TestObj() # 匹配存在且大于49,返回True result = myfunction(obj, greater_than("property.sub_property", 49)) print(result) # 输出:True
内容的提问来源于stack exchange,提问作者Cherry
相关产品推荐
相关产品推荐

