鱼C论坛

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

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

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

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

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

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


f = outer()
b = f()
c = f()
d = 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两处的代码改一下看看效果。多研究几次就会懂了

无标题.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 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 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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()

评分

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

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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两处的代码改一下看看效果。多研究几次就会懂了

无标题.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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()

评分

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

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-7-28 22:02:03 | 显示全部楼层
谢谢楼主!
祝楼主早日学成!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-12-22 23:13

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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