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?
-
You've completely changed your code sample since I posted that commentSayse– Sayse2022年03月18日 09:03:12 +00:00Commented Mar 18, 2022 at 9:03
2 Answers 2
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}
2 Comments
exec! How would you get something out of exec?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.