Лямбда-функция для классов в python?

Должен быть простой способ сделать это, но каким-то образом я могу обвести вокруг себя голову. Лучший способ, которым я могу описать то, что я хочу, – это лямбда-функция для класса. У меня есть библиотека, которая ожидает в качестве аргумента необоснованной версии класса для работы. Затем он создает экземпляр класса, над которым он должен работать. Проблема в том, что я хочу иметь возможность динамически создавать версии класса, переходить в библиотеку, но я не могу понять, как это сделать, поскольку библиотека ожидает неизученной версии. В приведенном ниже коде описывается проблема:

class Double: def run(self,x): return x*2 class Triple: def run(self,x): return x*3 class Multiply: def __init__(self,mult): self.mult = mult def run(self,x): return x*self.mult class Library: def __init__(self,c): self.c = c() def Op(self,val): return self.c.run(val) op1 = Double op2 = Triple #op3 = Multiply(5) lib1 = Library(op1) lib2 = Library(op2) #lib3 = Library(op3) print lib1.Op(2) print lib2.Op(2) #print lib3.Op(2) 

Я не могу использовать общий класс Multiply, потому что сначала должен создать его экземпляр, который разбивает библиотеку «AttributeError: экземпляр Multiply не имеет метода вызова ». Не меняя класс библиотеки, есть ли способ сделать это?

5 Solutions collect form web for “Лямбда-функция для классов в python?”

Лямбды вообще не нужно. лямбда – это просто синтаксический сахар, чтобы определить функцию и использовать ее одновременно. Подобно тому, как любой лямбда-вызов может быть заменен явным def, мы можем решить вашу проблему, создав настоящий класс, соответствующий вашим потребностям и возвращающий его.

 class Double: def run(self,x): return x*2 class Triple: def run(self,x): return x*3 def createMultiplier(n): class Multiply: def run(self,x): return x*n return Multiply class Library: def __init__(self,c): self.c = c() def Op(self,val): return self.c.run(val) op1 = Double op2 = Triple op3 = createMultiplier(5) lib1 = Library(op1) lib2 = Library(op2) lib3 = Library(op3) print lib1.Op(2) print lib2.Op(2) print lib3.Op(2) 

Действительно ли библиотека указывает, что она хочет «неинициализированную версию» (т.е. ссылку на класс)?

Мне кажется, что библиотека действительно хочет объектную фабрику. В этом случае допустимо ввести:

 lib3 = Library(lambda: Multiply(5)) 

Чтобы понять, как работает лямбда, рассмотрите следующее:

 Multiply5 = lambda: Multiply(5) assert Multiply5().run(3) == Multiply(5).run(3) 

Это своего рода обман, но вы можете дать вашему классу __call__ метод __call__ который возвращает себя:

 class Multiply: def __init__(self,mult): self.mult = mult def __call__(self): return self def run(self,x): return x*self.mult 

Таким образом, когда библиотека вызывает c() она фактически вызывает c.__call__() который возвращает нужный объект.

 def mult(x): def f(): return Multiply(x) return f op3 = mult(5) lib3 = Library(op3) print lib3.Op(2) 

Если я правильно понимаю ваше проблемное пространство, у вас есть общий интерфейс, который принимает один аргумент, который вызывается с использованием класса Library . К сожалению, вместо того, чтобы вызывать функцию, Library предполагает, что функция завершена в класс с помощью метода run .

Вы можете создавать эти классы программно. Классы могут быть возвращены методами, и благодаря концепции замыканий вы должны иметь возможность обернуть любую функцию в классе, который соответствует вашим потребностям. Что-то вроде:

 def make_op(f): class MyOp(object): def run(self, x): return f(x) return MyOp op1 = make_op(lambda x: return x*2) op2 = make_op(lambda x: return x*3) def multiply_op(y): return make_op(lambda x: return x*y) op3 = multiply_op(3) lib1 = Library(op1) lib2 = Library(op2) lib3 = Library(op3) print( lib1.Op(2) ) print( lib2.Op(2) ) print( lib3.Op(2) ) 

Говоря об этом, изменение библиотеки для выполнения функции, а затем предоставление функций, вероятно, является более эффективным способом сделать это.

Interesting Posts

Расписание времени и даты запуска сценария

Как читать csv, хранящийся в S3 с помощью csv.DictReader?

Эквивалент string.ascii_letters для строк unicode в python 2.x?

Насколько медленным является конкатенация строк Python и str.join?

Python – возврат из обратного вызова Tkinter

Использование текстового файла для размещения слов в форме сетки

Как использовать кодировку «hex» в Python 3.2 или выше?

Изменение глобальной переменной с тем же именем, что и локальная переменная

Базовая сеть с Pygame

Установка модулей с помощью pip, "не удалось разобрать CPython sys.version"

Распределение распределения, добротность посадки, значение p. Можно ли это сделать с помощью Scipy (Python)?

Как объединить строки и преобразовать их в столбцы

объявление глобальной динамической переменной в python

Python Numpy – присоединить три массива к матрице или 3D-массиву

Символьное представление числа с плавающей запятой в python

Python - лучший язык программирования в мире.