1

I would like to exec() code in the context of another function. Just doing it naively like

def f1():
 exec("b = 5")
def f2():
 f1()
 print(b)
f2()

won't work because b is not defined in f2:

Traceback (most recent call last):
 File "/tmp/s.py", line 10, in <module>
 f2()
 File "/tmp/s.py", line 7, in f2
 print(b)
NameError: name 'b' is not defined

I do not want to pass "b = 5" to f2.

Is it perhaps possible to pass the context of f2 to exec? Any hints?

asked Mar 18, 2022 at 8:56
1
  • You've completely changed your code sample since I posted that comment Commented Mar 18, 2022 at 9:03

2 Answers 2

3

You can give exec contexts through the two other parameters it supports:

exec(object[, globals[, locals]])

So to marshal the context from the previous function, include those as well. For example to marshal the local context only:

>>> def f1(code, ctx):
... exec(code, {}, ctx)
>>> def f2():
... a = 42
... f1("print(a + 1)", locals())
>>> f2()
43

To work with the modified context in future calls, own the context you're sending in yourself:

>>> def f2():
... ctx = {'a': 42}
... f1("a += 1", ctx)
... print(ctx)
...
>>> f2()
{'a': 43}
answered Mar 18, 2022 at 9:02
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks Mats. Thats already great for getting context into exec! How would you get something out of exec?
You own the context instead, i.e. you give a dict that you keep a reference to, and that dict will be modified as the context. I've added an example to my answer.
0

You could do something like this

class Context:
 pass
def f1(code, c):
 exec(code)
def f2():
 c = Context()
 c.a = 42
 f1("print(c.a + 1)", c)
f2()

where you add the variable to a context class and pass that along.

answered Mar 18, 2022 at 9:04

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.