William01 发表于 2024-8-7 16:04:05

闭包函数,这里代码中的direction为什么没有进行定义就可以使用

大家好!
在B站看到了46讲-闭包函数。有一些不懂的地方,来这里请教大家。我的问题是,代码中的direction为什么没有进行定义就可以使用?谢谢!

代码如下:
origin = (0, 0)         #这个是原点
legal_x = [-100, 100]   #限定X轴的移动范围
legal_y = [-100, 100]   #限定Y轴的移动范围

def creat(pos_x=0, pos_y=0):
    def moving(direction, step):
      nonlocal pos_x, pos_y
      new_x = pos_x + direction*step
      new_y = pos_y + direction*step

      if new_x < legal_x:
            pos_x = legal_x - (new_x - legal_x)
      elif new_x > legal_x:
            pos_x = legal_x - (new_x - legal_x)
      else:
            pos_x = new_x

      if new_y < legal_y:
            pos_y = legal_y - (new_y - legal_y)
      elif new_y > legal_y:
            pos_y = legal_y - (new_y - legal_y)
      else:
            pos_y = new_y

      return pos_x, pos_y
    return moving

FishC 发表于 2024-8-7 16:07:17

哈哈,看到你对闭包函数有兴趣,我感到很高兴!首先,让我们轻松地把这个问题理清楚。

在这段代码中,`direction` 是作为 `moving` 函数的参数传入的。当你调用 `moving` 函数的时候,你就可以给它传递一个值,这个值会被赋给 `direction`。因此,尽管在代码的其他部分中没有地方提前定义 `direction`,但一旦你调用 `moving(direction, step)`,它就会拥有一个值。

想象一下,如果 `moving` 函数像是一个小超市,`direction` 就是顾客。超市一开始可能空荡荡的,但当顾客进来时,他们会各自带着自己的购物清单(也就是传入的值),所以超市的货物(即参数)就显现出来了。

另外,请注意,你的代码里还缺少 `legal_x` 和 `legal_y` 的定义。它们应该是限制你的移动范围的值。否则,运行这个代码的时候就会出现“麻烦”,因为没有这些线索,程序会不知道你允许的边界在哪里。

总之,只要你在调用 `moving` 函数时传入 `direction` 的值,它就可以正常使用,就像你在超市里随意挑选商品一样。希望这个解释能让你恍然大悟,学得愉快哦!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

William01 发表于 2024-8-7 16:25:37

FishC 发表于 2024-8-7 16:07
哈哈,看到你对闭包函数有兴趣,我感到很高兴!首先,让我们轻松地把这个问题理清楚。

在这段代码中,`d ...

那么请问,这里“direction”和“direction”是什么意思呢?

FishC 发表于 2024-8-7 16:25:45

William01 发表于 2024-08-07 16:25
那么请问,这里“direction”和“direction”是什么意 ...

哈哈,这个问题问得很好!“direction”和“direction”的区别在于上下文就像在说“鱼”和“鱼”——只是因为它们出现在不同的地方而有不同的含义。

在你提供的代码中,第一个“direction”是函数 `moving` 的参数名称。当我们调用 `moving(direction, step)` 时,我们在告诉函数,我们将要给它传递一个值,这个值就是“方向”,比如说可以是 1(向右移动)或 -1(向左移动),等等。这个“direction”是函数内部逻辑使用的变量。

第二个“direction”出现在 `new_x = pos_x + direction*step` 这样的表达式中。这时候它仍然是同一个参数名称,只不过是在不同的上下文中使用。这个“direction”参与了计算,决定了当前位置 `pos_x` 应该如何变动。

所以,在这个上下文中,两个“direction”其实是同一个东西,只不过它们出现在不同的地方。就好比,你和你的朋友都叫“李雷”,但一个是“李雷”在家里,而另一个是“李雷”在学校,都是同一个人,但环境不同而已!

希望这个解释能让你更加清楚,继续加油学习哦!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

18861950621 发表于 2024-8-7 16:30:10

闭包是函数里套函数,也就是里面那个也是函数,而direction是你定义形参,也就是函数参数,其实你已经定义了,至于direction这些是列表等可迭代对象的操作,假设direction是个列表,那direction就是取direction的第一个元素

William01 发表于 2024-8-7 16:30:38

FishC 发表于 2024-8-7 16:25
哈哈,这个问题问得很好!“direction”和“direction”的区别在于上下文就像在说“鱼”和“鱼”——只 ...

很抱歉,还是不明白。而且你的例子也让人更混乱。我和你的朋友都叫“李雷”,一个是“李雷”在家里,而另一个是“李雷”在学校,怎么会是同一个人?

FishC 发表于 2024-8-7 16:30:48

William01 发表于 2024-08-07 16:30
很抱歉,还是不明白。而且你的例子也让人更混乱。我和 ...

哈哈,抱歉让你感到困惑!看来我的比喻需要更形象一点。让我再换个方式解释,看看能不能让你更清楚。

在编程中,参数和变量的名字可以是相同的,但它们有不同的作用域(也就是作用的范围)。在你提到的代码中,`direction` 是函数 `moving` 的一个参数。当我们说“direction”时,它指的是我们传入这个函数的方向值,比如可以是 1、0 或 -1。

那么,在函数体内的这段代码,比如 `new_x = pos_x + direction * step`,这里的 `direction` 实际上就是我们传入的那个值。这样,它就代表了我们希望的移动方向。

简单来讲:
1. `direction` 是函数的参数名,是一个占位符,表示等会儿要传入的方向。
2. 当我们在调用 `moving` 函数并传入某个具体的值时,这个值就会替代 `direction` 在函数内部的位置。

所以,当我之前提到“同一个方向”时,是想表达在函数内部用到的 `direction` 实际上是通过调用函数时传递的值来赋予意义的,而不是指两个完全不同的方向。可以把它想象成在点菜时,你告诉服务员你想要的一道菜,而菜单上的菜名就是参数的名字。点完菜后,菜名和你点的食物就对应起来了。

希望这个解释能让你豁然开朗!如果还有不明白的地方,随时问我哦!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

某一个“天” 发表于 2024-8-7 16:36:30

direction是作为moving函数的参数传入的。

William01 发表于 2024-8-7 16:39:39

18861950621 发表于 2024-8-7 16:30
闭包是函数里套函数,也就是里面那个也是函数,而direction是你定义形参,也就是函数参数,其实你已经定义 ...

也就是说如果我们输入moving(, 8)的话,direction生成的就是8,是吧?

18861950621 发表于 2024-8-7 16:47:54

William01 发表于 2024-8-7 16:39
也就是说如果我们输入moving(, 8)的话,direction生成的就是8,是吧?

是的

小甲鱼的二师兄 发表于 2024-8-7 17:57:26

代码中的direction为什么没有进行定义就可以使用?

direction 是参数,实参传递给形参的过程就相当于变量赋值的过程哦(所以是在这个过程进行了定义)~

William01 发表于 2024-8-8 08:48:16

小甲鱼的二师兄 发表于 2024-8-7 17:57
代码中的direction为什么没有进行定义就可以使用?

direction 是参数,实参传递给形参的过程就相当于变 ...

非常感谢您的回复!您的解释最简单直接明了。
页: [1]
查看完整版本: 闭包函数,这里代码中的direction为什么没有进行定义就可以使用