鱼C论坛

 找回密码
 立即注册
查看: 475|回复: 8

[已解决]函数嵌套

[复制链接]
发表于 2024-8-5 09:50:08 | 显示全部楼层 |阅读模式

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

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

x
B站第44讲,函数IV。请教一下,为什么函数1可以,函数2却不行?谢谢! 代码如下:

函数1
>>> def funA():
...     x = 520
...     def funB():
...         x = 880
...         print("In funB, x=", x)
...     funB()
...     print("In funA, x=", x)
... 
...     
>>> funA()
In funB, x= 880
In funA, x= 520


函数2
def funA():
    return 520
    def funB():
        return 880
        print(funB, x)
    funB()
    print(funA, x)

    
funA()
520
funB()
Traceback (most recent call last):
  File "<pyshell#25>", line 1, in <module>
    funB()
NameError: name 'funB' is not defined. Did you mean: 'funA'?

最佳答案
2024-8-5 10:00:49
William01 发表于 2024-08-05 09:59
还有就是怎么修改函数2使它达到和函数1一样的结果呢


好的,让我们来修复函数2,使它像函数1一样,顺利地输出结果!我们要确保 `funB()` 在 `funA()` 的返回之前被定义和调用。这里有一个简单的修改:
def funA():
    x = 520  # 定义 x
    def funB():
        x = 880  # 定义局部的 x
        print("In funB, x=", x)  # 打印局部的 x

    funB()  # 调用 funB()

    print("In funA, x=", x)  # 打印外部的 x
    return x  # 返回 x,以便我们可以显示它

funA()  # 最后调用 funA()

在这个版本中,我们把 `return 520` 移除了,因为我们希望在 `funA()` 中先运行 `funB()`,然后打印出两个不同作用域里的 `x` 值。执行后的结果会是:
In funB, x= 880
In funA, x= 520

这样就完美了!现在,这个函数既能正常调用内部的 `funB()` 也能通过外部的 `x` 输出。就像你第一次见到这两位朋友,终于成功地让他们聚在一起了,多么美妙的时刻啊!如果你把 `return` 放回去,确保它在所有打印操作之后,就能把 `x` 的值返回给调用者。

希望这个改动让你的函数和变量之旅更加畅快!如果还有其他问题,尽管问我哦!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-8-5 09:50:17 | 显示全部楼层
好的,来看看你的两个函数,咱们要揭开它们背后的神秘面纱!

首先,**函数1**工作得非常顺利,像个老练的魔术师:
def funA():
    x = 520
    def funB():
        x = 880
        print("In funB, x=", x)
    funB()
    print("In funA, x=", x)

funA()
在这个函数中,`funB()` 是在 `funA()` 的作用域内定义的,所以当你在 `funB()` 中打印 `x` 的时候,它会找到自己内部的 `x=880`。而当你回到 `funA()` ,则能够访问到它的 `x=520`。就像是两个房间,一个屋子里有520元,另一个屋子里有880元,互不影响。

现在,让我们看一下 **函数2**:
def funA():
    return 520
    def funB():
        return 880
        print(funB, x)
    funB()
    print(funA, x)

funA()

在这个函数的情况下,`funB()` 被定义在 `funA()` 内部,但由于它在 `return` 语句之后,因此这个函数根本不会被调用!就好比你在街上遇见了一个老朋友,正准备和他聊聊天的时候,你却把他推给了旁边的卖冰淇淋的摊子。结果你友好的“冰淇淋”,却再也没能见到你那个朋友了!

再加上,当你在 `funA()` 中尝试打印 `funB()` 和 `x` 时,`funB()` 还根本没有被执行过,因此 Python 没法识别它,给你一个 “NameError”。所以,最后的错误消息就像是在说:“嘿,你是不是搞错了?我记得你刚才提到过 `funA`,没听说过 `funB` 啊!”

总结一下,函数1可以正常运行,因为`funB()` 是在`funA()` 的作用域内,且在 `return` 之前被调用,而函数2则因为在 `return` 之后定义和调用 `funB()` 导致它失去了存在的机会,就像你偷天换日一样,完全没机会“露面”!

希望这解释对你有帮助,让你在函数的世界里畅游无阻!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-8-5 09:55:15 | 显示全部楼层
FishC 发表于 2024-8-5 09:50
好的,来看看你的两个函数,咱们要揭开它们背后的神秘面纱!

首先,**函数1**工作得非常顺利,像个老练 ...

是不是可以这么理解:在函数1中,`funA()`的执行过程还没完成,`funB()`就加入了进来,所以结果会是`funA()`和`funB()`一起。然而,在函数2中,`funA()`的执行过程已经完成了,所以不会有funA()`的出现。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-8-5 09:59:33 | 显示全部楼层
FishC 发表于 2024-8-5 09:50
好的,来看看你的两个函数,咱们要揭开它们背后的神秘面纱!

首先,**函数1**工作得非常顺利,像个老练 ...

还有就是怎么修改函数2使它达到和函数1一样的结果呢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-8-5 10:00:49 | 显示全部楼层    本楼为最佳答案   
William01 发表于 2024-08-05 09:59
还有就是怎么修改函数2使它达到和函数1一样的结果呢


好的,让我们来修复函数2,使它像函数1一样,顺利地输出结果!我们要确保 `funB()` 在 `funA()` 的返回之前被定义和调用。这里有一个简单的修改:
def funA():
    x = 520  # 定义 x
    def funB():
        x = 880  # 定义局部的 x
        print("In funB, x=", x)  # 打印局部的 x

    funB()  # 调用 funB()

    print("In funA, x=", x)  # 打印外部的 x
    return x  # 返回 x,以便我们可以显示它

funA()  # 最后调用 funA()

在这个版本中,我们把 `return 520` 移除了,因为我们希望在 `funA()` 中先运行 `funB()`,然后打印出两个不同作用域里的 `x` 值。执行后的结果会是:
In funB, x= 880
In funA, x= 520

这样就完美了!现在,这个函数既能正常调用内部的 `funB()` 也能通过外部的 `x` 输出。就像你第一次见到这两位朋友,终于成功地让他们聚在一起了,多么美妙的时刻啊!如果你把 `return` 放回去,确保它在所有打印操作之后,就能把 `x` 的值返回给调用者。

希望这个改动让你的函数和变量之旅更加畅快!如果还有其他问题,尽管问我哦!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-8-5 10:10:01 | 显示全部楼层
FishC 发表于 2024-8-5 10:00
好的,让我们来修复函数2,使它像函数1一样,顺利地输出结果!我们要确保 `funB()` 在 `funA()` 的返回 ...

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

使用道具 举报

发表于 2024-8-5 13:53:22 | 显示全部楼层
没定义x,
funB在内部
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-8-5 14:30:27 | 显示全部楼层

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

使用道具 举报

发表于 2024-8-6 15:05:55 | 显示全部楼层
没错!你的理解非常到位,绝对可以这么说!

在 **函数1** 中,`funA()` 的执行过程还没有完成。也就是说,当 `funB()` 被调用的时候,`funA()` 里的代码仍然在运行中,正好是个“打酱油”的时候!这就让 `funB()` 有机会在 `funA()` 执行的环境中调用和使用变量。因此,你同时看到了 `funA()` 和 `funB()` 的输出。

而在 **函数2** 中,因为 `return 520` 一旦被执行,就意味着 `funA()` 结束了它的流程,任何在它内部定义但在 `return` 后的代码都被“抛弃”了,依然不得不说这是一种“严格的礼仪”,所以 `funB()` 根本没法被调用。简单来说,就是当你宣告“任务完成”后,所有未决的事务都被放在了一边,因此最后你只能得到 `520`,而 `funB()` 对你来说就像是一个消失的魔术师。

所以,总结一下:在函数的执行过程中,活跃的代码和变量都会被保留,功能完整;一旦返回了结果,之前的承诺就只能作罢了。这就像是“你今天能不能过来吃饭?啊,不好意思,我已经决定去健身了!”

希望这个解释让你更加清楚了!如有更多问题,随时欢迎提问哦!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-23 16:27

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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