Reputation: 2187
Below are 2 code snippets.
I would like to duplicate the effect of f1
, where an outer variable x
is modified by an inner function g
.
However, instead of defining an inner function g
, g
is obtained by executing/interpreting a string.
code:
def f1():
x = []
def g():
x.append(1)
g()
print x
def f2():
x = []
strr = "def g():\n x.append(1)\n"
exec(strr)
locals()["g"]()
print x
In f1
I get [1] as the print out, but in f2
I get x undefined
error. I would like to know how I can make the variable x
accessible in the string-defined function g
.
follow up:
What would happen if I want to apply a decorator to g? say I have a "timeout" decorator that fails a function if it takes too long to run:
def f1():
x = []
@timeout(1)
def g():
x.append(1)
g()
print x
edit: I managed to solve it as follows, since timeout is not defined locally, I have to move the definition of timeout from global to local, the proceed as usual.
def f2():
x = []
strr = "@timeout(1)\ndef g():\n x.append(1)\n"
locals()['timeout'] = globals()['timeout']
exec strr in locals()
locals()["g"]()
print x
Upvotes: 1
Views: 378
Reputation: 2137
For Python 3, use this.
def f2():
x = []
strr = "def g():\n x.append(1)\n"
exec(strr, locals())
locals()["g"]()
print(x)
f2()
Upvotes: 0
Reputation: 85432
You need to add the name space for exec
. Use the local name space (exec strr in locals()
) and it works:
def f2():
x = []
strr = "def g():\n x.append(1)\n"
exec strr in locals()
locals()["g"]()
print x
>>> f2()
[1]
Upvotes: 1