鱼C论坛

 找回密码
 立即注册
查看: 710|回复: 5

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

[复制链接]
发表于 2024-7-28 14:49:51 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
  1. def outer():
  2.     x = 0
  3.     def inner():
  4.         x += 1
  5.         print(f'x = {x}')
  6.     return inner


  7. f = outer()
  8. b = f()
  9. c = f()
  10. d = f()
复制代码


请问上面这个代码错在了哪里,应该如何解决?
最佳答案
2024-7-28 16:12:49
x += 1是要对x修改的,但是如果要修改,他就必须是内层函数的变量,但你还没定义x,于是就会报错:内层变量x未赋值

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

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

  1. y = 2

  2. def outer():
  3.     x = 0
  4.     global y #1
  5.     y += x
  6.     print(x)
  7.     def inner():
  8.         nonlocal x #2
  9.         x += 1
  10.         print(f"x = {x}")
  11.     return inner

  12. f = outer()
  13. b = f()
  14. c = f()
  15. d = f()
复制代码


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

无标题.png
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

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

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

  8. f = outer()
  9. f()  # 会输出 x = 1
  10. f()  # 会输出 x = 2
  11. f()  # 会输出 x = 3
复制代码


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

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-7-28 15:04:10 | 显示全部楼层
本帖最后由 jackz007 于 2024-7-28 16:31 编辑
  1. def outer():
  2.     x = 0
  3.     def inner():
  4.         nonlocal x          # 声明在 inner() 中所使用的变量 x 来自外部,如果没有此句,在 inner() 中只能读取 x,而不可以对 x 赋值(x 不可以出现在等号的左边)
  5.         x += 1              # 此句先访问 x 的值,再对其赋新值,如果没有 nonlocal 或 global 声明一定会出错。
  6.         print(f'x = {x}')
  7.     return inner
  8. f = outer()
  9. f()
  10. f()
  11. f()
复制代码

评分

参与人数 1荣誉 +3 鱼币 +3 贡献 +3 收起 理由
wbzxz + 3 + 3 + 3

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-7-28 16:12:49 | 显示全部楼层    本楼为最佳答案   
x += 1是要对x修改的,但是如果要修改,他就必须是内层函数的变量,但你还没定义x,于是就会报错:内层变量x未赋值

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

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

  1. y = 2

  2. def outer():
  3.     x = 0
  4.     global y #1
  5.     y += x
  6.     print(x)
  7.     def inner():
  8.         nonlocal x #2
  9.         x += 1
  10.         print(f"x = {x}")
  11.     return inner

  12. f = outer()
  13. b = f()
  14. c = f()
  15. d = f()
复制代码


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

无标题.png
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-7-28 16:46:04 | 显示全部楼层
从内层函数 inner 中访问 x 变量,它会先找 inner 中有没有定义,再找 outer 中有没有定义,最后找全局变量中有没有定义。在这个过程中只要找到了,就不再继续找了。
  1. x = 3
  2. def outer():
  3.     x = 2
  4.     def inner():
  5.         x = 1
  6.         print(f'x = {x}')
  7.     return inner
  8. f = outer()
  9. f()
  10. ##>>> x = 1
复制代码

但如果从 inner 中修改 x 变量(注意不只是赋值),只能修改 inner 函数内定义的 x 变量。如果 x 在 inner 函数内没有定义,就会报错。
这时在 inner 中加上 nonlocal x ,就告诉了 python :不要只在最里面找了,找找 outer 函数的吧
  1. def outer():
  2.     x = 0
  3.     def inner():
  4.         nonlocal x         
  5.         x += 1              
  6.         print(f'x = {x}')
  7.     return inner
  8. f = outer()
  9. f()
  10. f()
  11. f()
复制代码

评分

参与人数 1荣誉 +3 鱼币 +3 贡献 +3 收起 理由
wbzxz + 3 + 3 + 3

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-7-28 22:02:03 | 显示全部楼层
谢谢楼主!
祝楼主早日学成!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-22 06:11

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表