If I eval something in Python:
eval("a + b")
This will evaluate the expression using the current scope (both locals and globals).
What I am developing requires that an expression be evaluated "later". Such word implies that I want to keep the current scope (i.e. locals()
and globals()
). But I want to pass such values... transparently, or fetch them from an upper stack frame. Consider this implementation (actually, this one exists):
def __eval(self, expr):
if isinstance(expr, (list, tuple, set, frozenset, dict, Expression)):
return Expression.eval(expr, self)
elif callable(expr):
try:
return expr(self)
except (AttributeError, IndexError, KeyError, TypeError):
return UNDEFINED
else:
try:
return eval(expr, {}, {'self': self})
except (AttributeError, IndexError, KeyError, TypeError):
return UNDEFINED
This implementation is explained as follows:
locals()
and globals()
.I know I could explicitly call:
o._O__eval("self.a + self.b", globals(), locals())
#THIS WOULD REQUIRE to alter the method to allow two additional dict parameters
#NO, I will not call this function directly, but lets follow the example
But I'd like to get such globals()
and locals
without the user passing it explicitly and make use of such values in the eval
.
Question: Is it possible to get the locals()
and globals()
from an upper stack frame?
You should really consider just passing in globals()
and locals()
:
def __eval(self, expr, eval_globals=None, eval_locals=None):
if eval_globals is None:
eval_globals = globals()
if eval_locals is None:
eval_locals = eval_globals()
If that is not an option for you, you can access the parent frame with the sys._getframe()
function, and the locals and globals are attributes on that frame:
def __eval(self, expr, eval_globals=None, eval_locals=None):
call_frame = sys._getframe(1)
eval_globals, eval_locals = call_frame.f_globals, call_frame.f_locals
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments