你應該分析的表達,並與語法樹工作,以解決這個問題。以下是一個可用於示例表達式的不完整示例。你可以展開它支持更多的語法結構:
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
是否有一組有限的查詢?您可以考慮在模型或經理上製作一系列方法。 –