LEEFEI571 发表于 昨天 22:16

关于Python课程中关于闭包函数的困惑

小甲鱼老师在讲解闭包函数的时候,举以下的例子:

def outer():
    x = 0
    y = 0
    def inner(x1, y1):
      nonlocal x, y
      x += x1
      y += y1
      print(f"现在x={x}, y = {y}")
    return inner

我的困惑是在执行move = outer()后,运行move(1,2)后,外部函数作用域中的x、y函数的值是不是也都分别变成1、2了?

还有个问题,我如果想对上述案例进行修改,想实现在执行内部函数前、后时,外部函数作用域中的x、y值分别是多少?以及内部函数作用域中x1、y1的值分别是多少?我写的代码如下:

def outer():
    x = 0
    y = 0
    print(f"执行内部函数前,外部函数作用域中:x={x}, y = {y}")
    def inner(x1, y1):
      nonlocal x, y
      x += x1
      y += y1
      print(f"内部函数作用域中:x={x}, y = {y}")
    return inner
    print(f"执行内部函数后,外部函数作用域中:x={x}, y = {y}")

但执行后有2个问题:
1、执行move = outer()后,只显示“执行内部函数前,外部函数作用域中:x=0, y = 0”,并没有打印出来“执行内部函数后,外部函数作用域中:x=0, y = 0”。
2、执行move(1,2)后,只显示“内部函数作用域中:x=1, y = 2”,并没有执行外部函数作用域中的两个print语句。

麻烦大佬帮忙指点一下迷津,谢谢!

FishC 发表于 昨天 22:17

第一个问题的解答:

是的,执行 move = outer() 后,再运行 move(1,2),外部函数作用域中的 x 和 y 的值会分别变成 1 和 2。这是因为 inner 函数使用了 nonlocal 关键字,使得对 x 和 y 的修改作用于 outer 函数的作用域。闭包保留了这些变量的引用,所以每次调用 move 都会更新这些值。

第二个问题的解答:

你的代码有两个关键问题:

1. print(f"执行内部函数后,外部函数作用域中:x={x}, y = {y}") 位于 return inner 语句之后。在 Python 中,return 会立即结束函数,因此这行代码永远不会被执行。

2. 当执行 move(1,2) 时,你只是在调用 inner 函数,而 outer 函数中的 print 语句只在最初调用 outer() 时执行一次,不会在每次调用 inner 时重复执行。

修改建议:

如果你想在每次调用内部函数前后打印外部函数作用域的值,以及内部函数的参数,可以将打印语句放在 inner 函数内部。例如:


def outer():
    x = 0
    y = 0
    print(f"初始化外部函数作用域:x={x}, y={y}")
    def inner(x1, y1):
      nonlocal x, y
      print(f"执行内部函数前,外部函数作用域:x={x}, y={y}")
      print(f"内部函数参数:x1={x1}, y1={y1}")
      x += x1
      y += y1
      print(f"执行内部函数后,外部函数作用域:x={x}, y={y}")
    return inner

move = outer()
move(1,2)


执行上述代码后,输出会显示:

初始化外部函数作用域:x=0, y=0
执行内部函数前,外部函数作用域:x=0, y=0
内部函数参数:x1=1, y1=2
执行内部函数后,外部函数作用域:x=1, y=2


这样,你就可以清晰地看到每次调用内部函数时,外部函数作用域的值变化以及内部函数的参数值。注意,外部函数的初始化打印只执行一次,而内部函数中的打印会在每次调用时执行。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
页: [1]
查看完整版本: 关于Python课程中关于闭包函数的困惑