In my current project, I am constructing functions dynamically by assembling a string, executing this string, then appending the resulting functions to a list. This works well inside a console, even when looped, but strangely does not work when I attempt to do the same thing inside a class object. Do you know why, and how I could get this to work?
The example snippet below is a minimal example. Constructing a function from a string is not an issue inside the main script, but when used inside a class object, the function is no longer assembled and an attempt to append it to a list returns an error.
import numpy as np # Create a string for a function funstr = "def fun1(x): return x" # Create a function exec(funstr) # Call the function print('Evaluate the function:') print(fun1(5)) print('Success!') # Create functions in a loop funlist = [] for i in range(5): funstr = "def fun2(x): return x+"+str(i) exec(funstr) funlist.append(fun2) # Check if the stored functions work print('Evaluate the list functions:') for i in range(5): print(funlist[i](5)) print('Success!') # Try the same thing in a class class testobject: def build_functions(self): # Do the same thing we did outside inside the class self.funlist = [] for i in range(5): funstr = "def fun3(x): return x+"+str(i) exec(funstr) print("Here, a function fun3 should have been assembled. For some reason, it hasn't been.") # !! Here, the function crashes because 'fun3' does not exist. !! self.funlist.append(fun3) print('Evaluate the list functions inside the object:') for i in range(5): print(self.funlist[i](5)) # Initialize an object obj = testobject() # Create the functions inside obj.build_functions()
Advertisement
Answer
fun3
is being defined in the local scope, but self.funlist.append(fun3)
is looking for the variable fun3
in the global scope (because there’s no local variable definition visible in the source code of the function).
You can use the locals()
function to get a dictionary of the local variables.
self.funlist.append(locals()['fun3'])