zeniapy
zeniapy

Reputation: 175

Anonymous function / Closure issue

I want to create a class Objective with an implemented call-function. The clue is, when initializing the Objective class a variable called function is handed over which can be either a mathematical function string or a python function itself. The __init__ has now the task to find out what the input is (string or callable function) and declare the variable/function func, which is return of the __call__. The code right now looks a little like this:

class Objective():
    def __init__(self, function):
        if isinstance(function, str):
            def func(self,x):
               return eval(function,x)

        elif callable(function):
            self.func = function

    def __call__(self, x):
        return self.func(x)

And the declaration could look a little something like this:

def calc1(x):
    return x+1
f = Objective(calc1)
f(1) --> f = 2

OR

f2 = Objective("x+1")
f2(1) --> f2 = 2

Now, as some of you might already noticed, the code won't work if the input is a string, because the definition of the function func only works within the __init__ (and yes, I know, the implementation of eval is not 100% correct either, but for simplicity I wrote it like this). My question is, how do I declare the function func within the if statement of the __init__ function? I hope I could explain my issue understandably.

Upvotes: 0

Views: 43

Answers (1)

juanpa.arrivillaga
juanpa.arrivillaga

Reputation: 96257

The way you add any instance variable, self.func = func:

class Objective():
    def __init__(self, function):
        if isinstance(function, str):
            def func(x): # no need for self
               return eval(function, locals())
            self.func = func # here

        elif callable(function):
            self.func = function

    def __call__(self, x):
        return self.func(x)

Note, you don't need self in your definition of func. Also note, you haven't used an anonymous function anywhere. You've used a normal function definition.

Finally, (even though you probably shouldn't be doing this), you need to get x into the namespaces available to eval, so, something to the effect of:

return eval(function, locals())

Upvotes: 2

Related Questions