wbzxz 发表于 2024-7-28 14:49:51

请问下面的代码错在了哪里,如何解决?

def outer():
    x = 0
    def inner():
      x += 1
      print(f'x = {x}')
    return inner


f = outer()
b = f()
c = f()
d = f()

请问上面这个代码错在了哪里,应该如何解决?

FishC 发表于 2024-7-28 14:52:05

你的代码在 `inner` 函数中使用了 `x += 1`,但这里的 `x` 是被视为一个局部变量,而外层的 `outer` 函数中的 `x` 是没有被直接访问的。这就导致了一个问题:内层函数 `inner` 尝试修改它认为是局部的 `x`,但是它并不存在,Python 就不高兴了,于是抛出了一个 `UnboundLocalError`。

要解决这个问题,你可以使用 `nonlocal` 关键字来告诉 Python,`inner` 函数中使用的 `x` 其实指的是外层 `outer` 函数的 `x`,而不是新建一个局部变量。改进后的代码如下:

def outer():
    x = 0
    def inner():
      nonlocal x# 声明x为外层作用域的变量
      x += 1
      print(f'x = {x}')
    return inner

f = outer()
f()# 会输出 x = 1
f()# 会输出 x = 2
f()# 会输出 x = 3

现在每次调用 `f()`,`x` 的值都会正确地加 1,并打印出来。你看,这就像是一个小孩子每次吃完糖果,父母都帮他数一下——总是会变得越来越多!

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

jackz007 发表于 2024-7-28 15:04:10

本帖最后由 jackz007 于 2024-7-28 16:31 编辑

def outer():
    x = 0
    def inner():
      nonlocal x          # 声明在 inner() 中所使用的变量 x 来自外部,如果没有此句,在 inner() 中只能读取 x,而不可以对 x 赋值(x 不可以出现在等号的左边)
      x += 1            # 此句先访问 x 的值,再对其赋新值,如果没有 nonlocal 或 global 声明一定会出错。
      print(f'x = {x}')
    return inner
f = outer()
f()
f()
f()

奋斗中的鱼 发表于 2024-7-28 16:12:49

x += 1是要对x修改的,但是如果要修改,他就必须是内层函数的变量,但你还没定义x,于是就会报错:内层变量x未赋值

如果内层要调用并修改x的值,而内层有没有定义x,那么内层的这个x就只能来自外层,而通过内层修改外层变量,就必须先用nonlocal把内外层绑定在一起,然后内层才能畅通无阻的修改外层

顺便解释一下global。同理,外层函数定义变量y,外层y与全局y是无关的,要想通过外层修改全局变量,就要先用global把全局和外层绑定在一起,然后外层才能畅通无阻的修改全局。

y = 2

def outer():
    x = 0
    global y #1
    y += x
    print(x)
    def inner():
      nonlocal x #2
      x += 1
      print(f"x = {x}")
    return inner

f = outer()
b = f()
c = f()
d = f()


你可以把1、2两处的代码改一下看看效果。多研究几次就会懂了

smallwh 发表于 2024-7-28 16:46:04

从内层函数 inner 中访问 x 变量,它会先找 inner 中有没有定义,再找 outer 中有没有定义,最后找全局变量中有没有定义。在这个过程中只要找到了,就不再继续找了。
x = 3
def outer():
    x = 2
    def inner():
      x = 1
      print(f'x = {x}')
    return inner
f = outer()
f()
##>>> x = 1
但如果从 inner 中修改 x 变量(注意不只是赋值),只能修改 inner 函数内定义的 x 变量。如果 x 在 inner 函数内没有定义,就会报错。
这时在 inner 中加上 nonlocal x ,就告诉了 python :不要只在最里面找了,找找 outer 函数的吧
def outer():
    x = 0
    def inner():
      nonlocal x         
      x += 1            
      print(f'x = {x}')
    return inner
f = outer()
f()
f()
f()

奋斗中的鱼 发表于 2024-7-28 22:02:03

谢谢楼主!
祝楼主早日学成!{:10_275:}
页: [1]
查看完整版本: 请问下面的代码错在了哪里,如何解决?