关键字参数和dict解包会产生不同的结果

时间:2017-03-25 00:32:56

标签: python kivy

我很难过。为什么以下两段代码的行为不一样?

1)

for attr in ("size", "pos"):
    self.bind(**{attr: lambda *args: setattr(self.background, attr, self.__getattribute__(attr))})

2)

self.bind(size=lambda *args: setattr(self.background, "size", self.__getattribute__("size")))
self.bind(pos=lambda *args: setattr(self.background, "pos", self.__getattribute__("pos")))

在第一个示例中,直接给出了关键字参数。 另一方面,通过解包dict来给出关键字参数。

Kivy奇怪的怪癖还是 getattribute 的东西?

1 个答案:

答案 0 :(得分:4)

这是闭包在Python中的工作方式:你的内部函数(在这种情况下是一个lambda)捕获对变量attr本身的引用,而不是它的值。如果在创建函数后更改attr,则函数中使用的attr值也会更改。因此,你的两个lambda最终都引用了attr的相同值(循环中看到的最后一个"pos")。

要解决此问题,您可以使用lambda中的默认参数值捕获值。在构造函数时,这些是完全评估的。

for attr in ("size", "pos"):
    self.bind(**{attr: lambda *args, attr=attr: setattr(self.background, attr, self.__getattribute__(attr))})