Reputation: 58791
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?
Upvotes: 1
Views: 608
Reputation: 52822
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}
Upvotes: 2
Reputation: 26
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.
Upvotes: 0