I'm going to pass a function dynamically to another class as shown below
class simulator(object):
def __init__(self, fn_):
print(self.test(fn_))
def test(self, fn):
return fn(self, 20)
class t(object):
s = 'def get_fitness(x, y):\n return x+y'
exec(s)
def fnGetFitness(self,genes):
return get_fitness(genes, 10)
simulator(fnGetFitness)
t()
but i face error below:
File "N:/Job/GA/mine/dyn.py", line 25, in fnGetFitness
return get_fitness(genes, 10)
NameError: name 'get_fitness' is not defined
i guess its something related to scopes but i can't handle it anyone on this?
EDIT :
this is a simpler code, showing the problem :
class t(object):
def __init__(self):
exec('def get_fitness(x, y):\n return x+y')
print(get_fitness(2,3))
t()
nothing to do with
exec. What you're doing is equivalent (with safety removed) to:but your method definition is at class level, but not on the
simulatorclass.simulator(fnGetFitness)callsfnGetFitnessout oftclass context, so it doesn't know your new function.That cannot work (also
get_fitnessshould be decorated as@staticmethodbecause it doesn't have aselfparameter)What works is to define dynamically (or not) the function at global level so class can call it
that fixed it, but honestly I'm puzzled about the purpose (already took me a while to figure out how to make something run from your code)
EDIT: a simpler and somehow different (and
execrelated) code has been posted in comments:this raises
NameError: name 'get_fitness' is not definednow this has to do with
exec. When__init__is parsed,get_fitnessisn't known because the parser didn't see it as a local variable, even if at the time of execution, it is set inlocals()dictionary byexec(related: why is 'ord' seen as an unassigned variable here?).A workaround is to fetch the function in the local variables like this:
this works & prints
5.