Nico Schlömer
Nico Schlömer

Reputation: 58791

Python exec() in other context

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

Answers (2)

MatsLindh
MatsLindh

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

Munsutari
Munsutari

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

Related Questions