Анонимная функция / Закрытие вопроса - PullRequest
0 голосов
/ 07 марта 2019

Я хочу создать класс Objective с реализованной функцией вызова.Подсказка в том, что при инициализации класса Objective передается переменная с именем function, которая может быть либо строкой математической функции, либо самой функцией python.__init__ теперь имеет задачу выяснить, что является вводом (строковая или вызываемая функция) и объявить переменную / функцию func, которая является возвращением __call__.Код прямо сейчас выглядит примерно так:

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)

И объявление может выглядеть примерно так:

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

ИЛИ

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

Сейчас, как некоторые из вас, возможно, уже заметили, код не будет работать, если ввод является строкой, потому что определение функции func работает только в пределах __init__ ( и , да, я знаюреализация eval тоже не на 100% правильная, но для простоты я написал это так).Мой вопрос: как мне объявить функцию func в операторе if функции __init__?Я надеюсь, что смогу объяснить мою проблему по понятным причинам.

1 Ответ

2 голосов
/ 07 марта 2019

Способ добавления любой переменной экземпляра, 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)

Обратите внимание, вам не нужно self в вашем определении func. Также обратите внимание, что вы нигде не использовали анонимную функцию. Вы использовали нормальное определение функции.

Наконец, (даже если вы, вероятно, не должны этого делать), вам нужно получить x в пространствах имен, доступных для eval, так что-то вроде:

return eval(function, locals())
...