你应该分析的表达,并与语法树工作,以解决这个问题。以下是一个可用于示例表达式的不完整示例。你可以展开它支持更多的语法结构:
import ast
def evaluate (expr, ref):
if isinstance(expr, ast.Module):
return evaluate(expr.body[0], ref)
elif isinstance(expr, ast.Expr):
return evaluate(expr.value, ref)
elif isinstance(expr, ast.Call):
args = [evaluate(x, ref) for x in expr.args]
kwargs = {kw.arg: evaluate(kw.value, ref) for kw in expr.keywords}
return evaluate(expr.func, ref)(*args, **kwargs)
elif isinstance(expr, ast.Attribute):
return getattr(evaluate(expr.value, ref), expr.attr)
elif isinstance(expr, (ast.Str, ast.Num)):
return ast.literal_eval(expr)
# special case; look up names on the reference object
elif isinstance(expr, ast.Name):
return getattr(ref, expr.id)
else:
print('Unknown type', type(expr))
您可以使用它像这样:
expr = "members.filter(gender='Male')"
evaluate(ast.parse(expr), referenceObject)
举个例子,我已经创建了下面的虚拟对象:
>>> def debug (*args, **kwargs):
print(args, kwargs)
>>> from types import SimpleNamespace
>>> ref = SimpleNamespace()
>>> ref.members = SimpleNamespace()
>>> ref.members.filter = debug
>>> evaluate(ast.parse("members.filter(gender='Male')"), ref)
() {'gender': 'Male'}
不没有很大的痛苦。你为什么想这样做?字符串从哪里来?这可能是更好的方法(换句话说,这是一个[XY问题](http://xyproblem.info/))。 –
@DanielRoseman我的用例:保存任何模型时,我需要一个用户列表,每个模型都有一组不同的用户可以更改。我曾经将用户作为“queryset”传递给用户,但是现在我正在使用代理,这是在另一台机器上完成的,因此我现在需要每个模型来简单告诉我如何查询数据库以获取其用户基础。 – MrKnotts
是否有一组有限的查询?您可以考虑在模型或经理上制作一系列方法。 –