I am trying to define an object master whose attribute/method decide can be called with an expression ex, but evaluation of that expression is postponed until some logic in decide asks for it (and it may even not do so). So, in code like this:
master.decide(ex)
it should be possible for ex to remain unevaluated if the logic in decide says so. In the code, ex stands for "arbitrary expression supplied by the client of my library." It can be as simple as 1 + 2 (where I wouldn't really care about lazy evaluation) to as complex as do_http_request().delete_record_from_database() (where I certainly do care).
Is such a thing possible? I am flexible on the syntax side, so if a solution exists which has to involve extra operators etc. around ex, I can consider it. But I would like ex to remain an expression.
I was thinking about (ab)using short-circuiting operators like and and or, but there doesn't seem to be a way to make those return something other than a boolean value.
The best I could come up with is wrapping ex in a lambda:
master.decide(lambda: ex)
def decide(ex):
if decide_to_do_it():
result = ex()
somehow_use(result)
Or passing it as a string and using eval:
master.decide('ex')
def decide(ex):
if decide_to_do_it():
result = eval(ex)
somehow_use(result)
(Yes, this one would have scoping issues).
Is there perhaps a magic function, trick, or something else which would allow me to keep ex as a plain expression?