我正在编写一段代码,需要验证两个用户是否在几个不同的标准下“匹配”。如果它有帮助,可以将其视为一个约会应用程序,我们会根据年龄,性别偏好,种族偏好等来匹配人们。这是一个有3个条件的例子,每个条件都是一个函数。
def is_match(row):
return True \
and ethnicity(user_a, user_b) \
and sexual_orientation(user_a, user_b) \
and age(user_a, user_b) \
现在,假设我想为邻近度添加另一个条件,我只想将它添加到函数中:
def is_match(row):
return True \
and ethnicity(user_a, user_b) \
and sexual_orientation(user_a, user_b) \
and age(user_a, user_b) \
and proximity(user_a, user_b)
当然,这对于小型应用程序来说是可行的,但我可以想象其他同事可能想要检查代码并将自己的条件传递给它,这看起来不够抽象。我知道这里必须有一个模式。我应该将每个函数作为数组传递吗?你会怎么推荐这样做?我正在使用Python,但您可以使用任何您想要演示模式的语言。
答案 0 :(得分:2)
我认为集合对于这样的任务是有益的,因为它比验证更具有比较性。我会举例给你:
user_a = {
'ethnicity': 1,
'sexual_orientation': 'straight',
'age': 37,
}
user_b = {
'ethnicity': 2,
'sexual_orientation': 'straight',
'age': 34,
}
differences = set(user_a.items()) ^ set(user_b.items()) # s.symmetric_difference(t)
commons = set(user_a.items()) & set(user_b.items()) # s.intersection(t)
print({'differences': differences, 'commons': commons})
输出:
{'differences': {('ethnicity', 2), ('ethnicity', 1), ('age', 37), ('age', 34)}, 'commons': {('sexual_orientation', 'straight')}}
所以你可以将两个用户的数据加载到dicts并进行比较。
答案 1 :(得分:1)
def is_match(list_of_functions, user_a, user_b):
return all([cur_fun(user_a, user_b) for cur_fun in list_of_functions])
编辑:
以下变体更有效,因为它会在遇到非True值时缩短,而不是必须评估所有函数:
def is_match(list_of_functions, user_a, user_b):
for cur_fun in list_of_functions
if not cur_fun(user_a, user_b):
return False
return True
答案 2 :(得分:1)
结帐Specification Pattern。这正是您所需要的。它用C#编写,但可以很容易地转换