python中的类的Lambda函数?

时间:2008-12-11 18:27:21

标签: python lambda

必须有一个简单的方法来做到这一点,但不知何故,我可以绕过它。我可以描述我想要的最好的方法是一个类的lambda函数。我有一个库,希望作为一个参数,可以使用一个未经实例化的类。然后它实例化类本身以继续工作。问题是我希望能够动态创建类的版本,传递给库,但我无法弄清楚如何做到这一点,因为库需要一个未实例化的版本。下面的代码描述了问题:

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实例没有调用方法”。如果不改变库类,有没有办法可以做到这一点?

6 个答案:

答案 0 :(得分:11)

图书馆是否真的指定它需要“未初始化的版本”(即类引用)?

在我看来,好像图书馆实际上想要一个对象工厂。在这种情况下,输入可以接受:

lib3 = Library(lambda: Multiply(5))

要了解lambda的工作原理,请考虑以下事项:

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

答案 1 :(得分:8)

根本不需要lambda。 lambda只是合成糖来定义一个函数并同时使用它。就像任何lambda调用可以用显式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)

答案 2 :(得分:1)

这有点作弊,但你可以给你的Multiply类一个返回自己的__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__()来返回你想要的对象。

答案 3 :(得分:1)

def mult(x):
    def f():
        return Multiply(x)
    return f


op3 = mult(5)
lib3 = Library(op3)
print lib3.Op(2)

答案 4 :(得分:1)

如果我正确理解你的问题空间,你有一个通用接口,它接受一个参数,使用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) )

话虽如此,更改库以获取功能然后提供功能可能是更好的方法。

答案 5 :(得分:0)

由于 const axios = require('axios'); // Make a request for a user with a given ID axios.get('/user?ID=12345') .then(function (response) { // handle success console.log(response); }) .catch(function (error) { // handle error console.log(error); }) .then(function () { // always executed }); // Optionally the request above could also be done as axios.get('/user', { params: { ID: 12345 } }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); }) .then(function () { // always executed }); // Want to use async/await? Add the `async` keyword to your outer function/method. async function getUser() { try { const response = await axios.get('/user?ID=12345'); console.log(response); } catch (error) { console.error(error); } } 是python类对象的默认类,并且调用一个类会创建该类的新实例,因此使用正确的参数调用type会导致一个新类。

type

my_class = type("my_class", (object,), {"an_attribute": 1}) 现在引用一个名为“ my_class”的新类,该类是my_class的子类,其属性名为“ an_attribute”,其值为1。由于方法也是类属性指向功能对象,您也可以将它们添加到属性字典中:

object

这是它的工作方式。我不建议您这样做,除非您绝对需要。在所有情况下的99%中,您没有。有关实现目标的干净方法,请参阅@Parker Coates的答案。