鱼C论坛

 找回密码
 立即注册
查看: 35|回复: 1

[已解决]关于第46讲函数(VI)动动手作业1

[复制链接]
发表于 昨天 22:44 | 显示全部楼层 |阅读模式

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

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

x
今天刚学到第46讲,函数(VI)。实话实话,从闭包学到现在,感到非常吃力,毕竟是python小白,
感觉有些知识是被动去理解,也就是顺着小鱼老师的代码去理解,不明白底层机制到底是什么。现在以
本标题作业提个问题,先把小鱼老师的源代码贴出来:
def type_check(correct_type):
    def outer(func):
        def inner(arg):
            if(type(arg) == correct_type):
                return func(arg)
            else:
                return "参数类型错误!"
        return inner
    return outer
   
   
print("<<<--- 测试整数 --->>>")
   
@type_check(int)
def double(x):
    return x * 2
   
print(double(2))      # 这里打印结果应该是 4
print(double("2"))    # 这里打印结果应该是 “参数类型错误”
   
print("\n<<<--- 测试字符串 --->>>")
   
@type_check(str)
def upper(s):
    return s.upper()
   
print(upper('I love FishC.'))   # 这里打印结果应该是 I LOVE FISHC
print(upper(250))               # 这里打印结果应该是 “参数类型错误”


问题是:在上面的函数定义中,第三层函数inner(arg)中参数arg哪儿来的?当然被动理解肯定是第二层函数out(func)
中的func传递来的。课堂中也没有讲解这种传递机制,但是被动理解非常不舒服。
最佳答案
昨天 22:46
你好!很高兴能帮助你理解这个问题。闭包和装饰器确实在初学时会有些吃力,但别担心,我们来一步步拆解它。

你的观察是正确的:inner(arg) 中的参数 arg 确实来自于你调用被装饰后的函数时传递的参数。它不是直接从 outer(func) 中的 func 传递来的,而是通过装饰器的链式调用机制实现的。

让我们用你的代码示例来解释:

当你有这样的装饰器应用:
  1. @type_check(int)
  2. def double(x):
  3.     return x * 2
复制代码

这实际上等价于:
  1. double = type_check(int)(double)
复制代码


现在,一步步分解:
1. type_check(int) 返回 outer 函数。
2. outer(double) 返回 inner 函数。
3. 所以,double 现在指向了 inner 函数。

当你调用 double(2) 时,实际上是在调用 inner(2),因此 arg 就是 2。在 inner 函数内部,它会检查 arg 的类型,如果正确,就调用原来的 func(arg)(即 double(2))。

简单总结:arg 来自你对装饰后函数的调用参数,而不是来自闭包的内部传递。装饰器的作用是“包装”原函数,在调用时添加额外的逻辑(比如类型检查)。

希望这个解释能让你更清楚底层机制。如果还有疑问,欢迎继续讨论!

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

使用道具 举报

发表于 昨天 22:46 | 显示全部楼层    本楼为最佳答案   
你好!很高兴能帮助你理解这个问题。闭包和装饰器确实在初学时会有些吃力,但别担心,我们来一步步拆解它。

你的观察是正确的:inner(arg) 中的参数 arg 确实来自于你调用被装饰后的函数时传递的参数。它不是直接从 outer(func) 中的 func 传递来的,而是通过装饰器的链式调用机制实现的。

让我们用你的代码示例来解释:

当你有这样的装饰器应用:
  1. @type_check(int)
  2. def double(x):
  3.     return x * 2
复制代码

这实际上等价于:
  1. double = type_check(int)(double)
复制代码


现在,一步步分解:
1. type_check(int) 返回 outer 函数。
2. outer(double) 返回 inner 函数。
3. 所以,double 现在指向了 inner 函数。

当你调用 double(2) 时,实际上是在调用 inner(2),因此 arg 就是 2。在 inner 函数内部,它会检查 arg 的类型,如果正确,就调用原来的 func(arg)(即 double(2))。

简单总结:arg 来自你对装饰后函数的调用参数,而不是来自闭包的内部传递。装饰器的作用是“包装”原函数,在调用时添加额外的逻辑(比如类型检查)。

希望这个解释能让你更清楚底层机制。如果还有疑问,欢迎继续讨论!

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-10-13 06:19

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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