某些软件包如SQLAlchemy和RethinkDB(我碰巧使用后者)需要将谓词表达式作为参数传递给函数。例如,RethinkDB的filter
方法(https://rethinkdb.com/api/python/filter/)要求第一个参数是ReQL语法表达式,而不是字符串。
但是,我想基于我收到的REST API查询字符串以编程方式构建此表达式。例如,我可能会收到一个查询字符串,例如:
/?filter=name%3D%3DNick&filter=score%3D%3DA,score%3D%3DB
在这种情况下,我想将此查询字符串转换为谓词:
r.row['name'] == 'Nick' & (r.row['score'] == 'A' | r.row['score'] == 'B')
我可以使用我写的递归函数生成这个谓词作为字符串:
def process_filters(data):
if isinstance(data, list):
return ' & '.join([process_filters(val) for val in data])
elif ',' in data:
or_filters = data.split(',')
return '(' + \
' | '.join(['(r.row["' + val.split('==', 1)[0] + '"] == ' + val.split('==', 1)[1] + ')' for val in or_filters]) + \
')'
else:
parts = data.split('==', 1)
return '(r.row["' + parts[0] + '"] == ' + parts[1] + ')'
这个函数给了我一个字符串所需的谓词。但是,RethinkDB不会将此参数作为字符串处理。
r.filter(process_filters(query_string))
上面的命令将不正常工作,因为r.filter
需要一个表达式,例如:
r.filter(r.row['name'] == 'Nick')
不是:r.filter("r.row['name'] == 'Nick'")
如何将参数转换为表达式,同时仍然保持以编程方式从字符串构建谓词的灵活性,如我所拥有的那样?
编辑:eval
实际 工作,但正如评论者指出的那样,这通常是不受欢迎的。我相信在这种特殊情况下它可能是最好的"解决方案,但我期待更多的想法...
答案 0 :(得分:0)
x = "name=Nick"
key, value = x.split('=')
query = {r.row[key]: value}
r.filter(**query)
参考:What does ** (double star/asterisk) and * (star/asterisk) do for parameters?