2

我正在尝试创建一个动画,我想要一个点和线列表来跟踪一个值。为此,我正在使用 ValueTracker 对象和更新程序方法。使用 ShowCreation,我已经将这些对象添加到场景中。我使用 for 循环为列表中的每个点和线添加更新程序(两个列表的长度相同):

 for i in range(len(x_points)):
    dots_cos[i].add_updater(
        lambda mob: mob.move_to(axes2.c2p(x_points[i], np.cos(omega.get_value()*x_points[i]))),
        # call_updater=False
        )
    dots_sin[i].add_updater(
        lambda mob: mob.move_to(axes2.c2p(x_points[i], np.sin(omega.get_value()*x_points[i]))),
        # call_updater=False
        )
    lines_cos[i].add_updater(
        lambda mob: mob.become(Line(axes2.coords_to_point(x_points[i], 0),
            axes2.coords_to_point(x_points[i], np.cos(omega.get_value()*x_points[i])), color=YELLOW)),
        # call_updater=False
        )
    lines_sin[i].add_updater(
        lambda mob: mob.become(Line(axes2.coords_to_point(x_points[i], 0),
            axes2.coords_to_point(x_points[i], np.sin(omega.get_value()*x_points[i])), color=RED)),
        # call_updater=False
        )

这没有按预期工作!发生的事情是,只有各个列表中的最后一个元素得到了更新,并且正常工作,而其余元素则从场景中消失了!我尝试在 上运行 for 循环zip(x_points, dots_cos, dots_sin, lines_cos, lines_sin),但结果仍然相同。

有趣的是,当我尝试使用 while 循环而不是循环的最后一次迭代来执行相同操作时,代码尝试将更新程序添加到 last+1 迭代,因此引发了 IndexOutOfBounds 异常。尽管像 print 语句这样的良性语句在 while 循环中运行良好。

此外,如果它很重要,则使用返回这些列表的用户定义函数生成点和线列表。

那么这里的问题是什么?add_updater 函数如何破坏像 for 循环这样基本的东西?

4

1 回答 1

3

您遇到了一个众所周知的在循环中构造 lambda 的问题。您的解决方案可能是:

lambda mob, i=i:  ...
于 2020-03-28T13:38:55.237 回答