首页 > 其他分享 >for 循环中使用 updater 的注意事项

for 循环中使用 updater 的注意事项

时间:2023-03-11 09:55:05浏览次数:48  
标签:random add 循环 updater 注意事项 np circle dot

例如,我想让三个圆及其圆心绕着原点旋转,其中圆通过 updater 移动到圆心上:

mobs = VGroup()
for i in range(3):
    dot = Dot()
    distance = 0.5 + np.random.random()*1.3
    angle = np.random.random()*2*PI
    dot.shift([distance*np.cos(angle), distance*np.sin(angle), 0])
    dot.add_updater(lambda z, dt: z.rotate(0.5*PI*dt, about_point=ORIGIN))
    circle = Circle().move_to(dot)
    circle.add_updater(lambda z: z.move_to(dot))
    mobs.add(dot, circle)
self.add(mobs)
self.wait(3)

但是实际上,看起来的效果好像是三个圆都围绕着同一个圆心,而不是各自的圆心

 

这其实是 for 循环中使用闭包而导致的,这是一个例子:

fs = []
for i in range(1, 4):
    def f():
         return i*i
    fs.append(f)

f1, f2, f3 = fs

print(f1(), f2(), f3())

你可能认为结果是 1, 4, 9,但实际上结果为 9, 9, 9

我的看法是,闭包的结果是返回一个函数,如果这个函数没有传入参数,那么就会产生问题。上面的例子中 f() 没有传入任何的参数,等到循环结束后,i 已经变成了 3,这时候 f1, f2, f3 其实是等价的,均返回 3*3

解决方法也很简单,只需要在 f() 中传入参数即可:

fs = []
for i in range(1, 4):
    def f(n):
        def g():
            return n*n  # 这里不能写成 i*i
        return g
    fs.append(f(i))

f1, f2, f3 = fs

print(f1(), f2(), f3())

 

我们回到最初的问题,lambda 本质上也是一个函数,我们需要改写一下,使得每个 updater 的函数均绑定到各自的对象上:

mobs = VGroup()
for i in range(3):
    def generate_updater(mob1, mob2):
        def updater(mob1):
            mob1.move_to(mob2)
        return updater  # 这里不用传入参数
    dot = Dot()
    distance = 0.5 + np.random.random()*1.3
    angle = np.random.random()*2*PI
    dot.shift([distance*np.cos(angle), distance*np.sin(angle), 0])
    dot.add_updater(lambda z, dt: z.rotate(0.5*PI*dt, about_point=ORIGIN))
    circle = Circle().move_to(dot)
    circle.add_updater(generate_updater(circle, dot))
    mobs.add(dot, circle)
self.add(mobs)
self.wait(3)

 

标签:random,add,循环,updater,注意事项,np,circle,dot
From: https://www.cnblogs.com/daxiangcai/p/17205325.html

相关文章

  • 可迭代对象和迭代器对象以及for循环的本质
    一、可迭代对象什么是可迭代对象:在数据类型的后面可以使用点加__iter__(.__iter__)来判断是不是可迭代对象不是可迭代对象:intfloatbool函数对象可迭代对象:s......
  • 面试之可迭代对象和迭代器对象以及for循环的本质
    一、可迭代对象什么是可迭代对象:在数据类型的后面可以使用点加__iter__(.__iter__)来判断是不是可迭代对象不是可迭代对象:intfloatbool函数对象可迭代对象:s......
  • Go循环判断
    if条件判断ifage>18{}elseifage==18{}else{}for循环continue:直接执行下一次循环break:直接退出循环//写法1fori:=0;i<3;i++......
  • DoWhile循环
    do...while循环对于while语句而言,如果不满足条件,则不能进入循环。但有时候我们需要即使不满足条件,也至少执行一次。do...while循环和while循环相似,不同的是,do...whil......
  • While循环
    循环结构while循环do...while循环for循环在Java5中引入了一种主要用于数组的增强型for循环while循环while是最基本的循环,它的结构为:while(布尔表达式......
  • 增强for循环
    增强for循环这里我们先只见一面,做个了解,之后数组我们重点使用Java5引入了一种主要用于数组或集合的增强型for循环。Java增强for循环语法如下:for(声明语句:表达......
  • For循环
    For循环虽然所有循环结构都可以用while或者do...while表示,但Java提供了另一种语句——for循环,使一些循环结构变得更加简单。for循环语句是支持迭代的一种通用结构,是最......
  • (转)Golang中time包用法及一些注意事项
    原文:https://blog.csdn.net/wade3015/article/details/109328485在我们日常软件开发过程中,经常会用到与时间相关的各种业务需求,下面来介绍golang中有关时间的一些基本用......
  • 阐述⼀下 JS 的事件循环
    事件循环⼜叫做消息循环,是浏览器渲染主线程的⼯作⽅式。在Chrome的源码中,它开启⼀个不会结束的for循环,每次循环从消息队列中取出第⼀个任务执⾏,⽽其他线程只需要在合......
  • python中的循环语句
    循环语句while循环​ 用于不固定次数的循环......