Feb-17-2021, 08:00 AM
Here is an attempt to do this with a function. In the following code, the function 'expression()' is executed by 'main()' and it uses the variables 'x' and 'y' defined in 'main()'.
The previous code prints 13, but if you comment the line 'y = 2' in 'main()', it prints 53.
import sys y = 10 class Caller: def __init__(self, frame): self.frame = frame def __getattr__(self, attr): try: return self.frame.f_locals[attr] except KeyError: return self.frame.f_globals[attr] def call(func, *args, **kwargs): f = sys._getframe(1) return func(Caller(f), *args, **kwargs) def spam(u): return 5 * u def expression(caller): return caller.x + spam(caller.y) def main(): x = 3 y = 2 print(call(expression)) if __name__ == '__main__': main()The only thing to do to make it work is to add a first parameter 'caller' in the function's signature and use it to get the variables from the calling namespace. Other parameters can be added to 'expression()' and passed in the 'call()' statement.
The previous code prints 13, but if you comment the line 'y = 2' in 'main()', it prints 53.