1

I am developing an Agent class for an evolutionary algorithm. I need to add a method to it that is generated from a string inherited from the parents. Here a minimal example

class Agent:
 def __init__(self, s='\tif x > y:\n\t\treturn 1'):
 self.f_template = f'def f(self, x,y):\n{s}'

I would like to have the method self.f(self, x,y) having self.f_template as a function body. I know I could add it later doing:

A = Agent()
exec(A.f_template)
A.f = partial(f, A)
>>> A.f(3,2)
1

But is it possible to achieve the same during __init__() and not after?

Simply doing the following raises NameError: name 'f' is not defined

class Agent:
 def __init__(self, s='\tif x > y:\n\t\treturn 1'):
 self.f_template = f'def f(self, x,y):\n{s}'
 exec(self.f_template)
 self.f = partial(f, self)
asked Sep 30, 2018 at 15:27

1 Answer 1

1

This is because the Python compiler looks at all the l-values in a code block when determining which variables are local, and in this case, f is not defined as an l-value, so the compiler complains at compilation time rather than at run time. This is not an issue in REPL where every line is compiled separately.

You can instead use the locals() dict to access a variable name that is produced dynamically:

class Agent:
 def __init__(self, s='\tif x > y:\n\t\treturn 1'):
 self.f_template = f'def f(self, x,y):\n{s}'
 exec(self.f_template)
 self.f = partial(locals()['f'], self)
answered Sep 30, 2018 at 16:16
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.