当您使用lambda
要创建每个方法,您需要将其绑定到当前本地范围。该范围有一个名为的变量实例method_value
,并且在每次循环后都会将其设置为新值。因为每个lambda
引用这个局部变量,它们都看到相同的值(例如,设置的最后一个值)。
如果您在不同的方法中创建 lambda,它将具有不同的作用域,因此您可以获得所需的行为:
class Klass(object):
pass
list1 = [('method1', 'value1'), ('method2', 'value2'), ('method10', 'value10')]
def make_attr(value):
return lambda self: value
for method_name, method_value in list1:
setattr(Klass, method_name, make_attr(method_value))
c = Klass()
print c.method1(), c.method2(), c.method10() # "value1, value2, value10"
Here, make_attr
创建一个新的作用域,因此该变量有唯一的实例value
,每个创建的 lambda 对应一个。
您还可以使用一个不错的技巧来创建内联 lambda 范围的变量,如下所示:
lambda self, val=method_value: val
Here, val
被赋值为method_value
在 lambda 声明时,为 lambda 的每个实例赋予其自己的值。这使您可以使用更紧凑的:
for method_name, method_value in list1:
setattr(Klass, method_name, lambda self, val=method_value:val))
最后,马蒂指出不同的答案 https://stackoverflow.com/a/33135707/925478如何修改我的make_attr
应用所需装饰器的函数:
def make_attr(value):
return mat.sell(mat.CanSet)(lambda self: value))