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 instance has no call method”的错误。在不改变库的情况下,有没有办法做到这一点呢?
6 个回答
3
这有点像是走捷径,但你可以给你的 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__()
,这个方法会返回你想要的对象。
13
这个库真的要求一个“未初始化的版本”(也就是一个类的引用)吗?
我觉得这个库其实想要的是一个对象工厂。在这种情况下,可以这样写:
lib3 = Library(lambda: Multiply(5))
要理解这个lambda是怎么工作的,可以考虑以下内容:
Multiply5 = lambda: Multiply(5)
assert Multiply5().run(3) == Multiply(5).run(3)
10
其实根本不需要用到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)