鱼C论坛

 找回密码
 立即注册
查看: 142|回复: 6

[已解决]闭包和装饰器

[复制链接]
发表于 2024-4-11 03:06:24 | 显示全部楼层 |阅读模式

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

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

x
能否举个其他的例子说明闭包和装饰器呢?小甲鱼课程46节和47节看了很多遍,还是没懂
最佳答案
2024-4-11 03:26:56
  1. def make_multiplier_of(n):
  2.     def multiplier(x):
  3.         return x * n
  4.     return multiplier

  5. # 创建一个乘以3的闭包函数
  6. times3 = make_multiplier_of(3)

  7. # 使用闭包函数
  8. print(times3(10))  # 输出 30

  9. # 创建另一个乘以5的闭包函数
  10. times5 = make_multiplier_of(5)

  11. # 使用闭包函数
  12. print(times5(10))  # 输出 50
复制代码

这个你可以理解吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-4-11 03:06:35 | 显示全部楼层
当然可以!我来给你举个例子。

首先,我们来看闭包的例子:

  1. def outer_func(msg):
  2.     def inner_func():
  3.         print(msg)
  4.     return inner_func

  5. my_func = outer_func("Hello")
  6. my_func()
复制代码


在这个例子中,`outer_func` 是一个外部函数,它接受一个参数 `msg`。`inner_func` 是一个内部函数,它打印出外部函数传递过来的 `msg`。`outer_func` 返回了 `inner_func`,这就形成了一个闭包。

在 `outer_func` 中,我们将 `inner_func` 这个函数作为返回值,而不是立即执行它。当我们调用了 `outer_func("Hello")` 后,它返回了 `inner_func` 函数,并将这个函数保存在 `my_func` 变量里。当我们调用 `my_func()` 时,它实际上是在执行内部函数 `inner_func`,并打印出了 "Hello"。

接下来,我们来看装饰器的例子:

  1. def decorator_func(original_func):
  2.     def wrapper_func():
  3.         print("装饰器开始")
  4.         original_func()
  5.         print("装饰器结束")
  6.     return wrapper_func

  7. @decorator_func
  8. def my_func():
  9.     print("我是原始函数")

  10. my_func()
复制代码


在这个例子中,`decorator_func` 是一个装饰器函数,它接受一个原始函数 `original_func` 作为参数,并返回一个新的函数 `wrapper_func`。在 `wrapper_func` 中,我们在调用原始函数之前和之后分别打印了一些信息,实现了对原始函数的装饰。

在 `my_func` 定义的上方,我们使用 `@decorator_func` 来装饰 `my_func`。这相当于执行了 `my_func = decorator_func(my_func)`。因此,当我们调用 `my_func()` 时,实际上是在执行装饰后的函数 `wrapper_func`。

希望这个例子能帮助你更好地理解闭包和装饰器的概念。如果还有疑问,请随时提问!

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

使用道具 举报

发表于 2024-4-11 03:26:56 | 显示全部楼层    本楼为最佳答案   
  1. def make_multiplier_of(n):
  2.     def multiplier(x):
  3.         return x * n
  4.     return multiplier

  5. # 创建一个乘以3的闭包函数
  6. times3 = make_multiplier_of(3)

  7. # 使用闭包函数
  8. print(times3(10))  # 输出 30

  9. # 创建另一个乘以5的闭包函数
  10. times5 = make_multiplier_of(5)

  11. # 使用闭包函数
  12. print(times5(10))  # 输出 50
复制代码

这个你可以理解吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-4-11 03:28:19 | 显示全部楼层
如果能理解上面闭包的调用,装饰器的执行原理就好理解很多:

  1. def my_decorator(func):
  2.     def wrapper():
  3.         print("Something is happening before the function is called.")
  4.         func()
  5.         print("Something is happening after the function is called.")
  6.     return wrapper

  7. @my_decorator
  8. def say_hello():
  9.     print("Hello!")

  10. # 调用装饰后的函数
  11. say_hello()
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-4-11 03:29:14 | 显示全部楼层
哈哈,上面 AI 的回复好像已经相当详细了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-4-11 10:42:47 | 显示全部楼层
本帖最后由 jackz007 于 2024-4-11 12:13 编辑

【闭包】:
  1. def fooA(a , b) :
  2.     def fooB(x , y) :
  3.         return (x + a) // (y - b)
  4.     return fooB

  5. fx1 = fooA(900 , 45)        # 以 a = 900 , b = 45 调用 fooA(a , b),得到其内嵌函数 fooB() 的调用句柄 fx1
  6. fx2 = fooA(150 , 15)        # 以 a = 150 , b = 15 调用 fooA(a , b),得到其内嵌函数 fooB() 的调用句柄 fx2
  7. print('%d' % fx1(30 , 75))  # 以 a = 900 , b = 45 , x = 30 , y = 75 调用 fooA() 的内嵌函数 fooB(x , y)
  8. print('%d' % fx2(30 , 75))  # 以 a = 150 , b = 15 , x = 30 , y = 75 调用 fooA() 的内嵌函数 fooB(x , y)
复制代码

【装饰器】:
  1. def fooA(fx) :                          # 调用参数 fx 就是被装饰函数 work() 的调用句柄
  2.     def fooB(x , y) :                   # 由于 work() 有 2 个输入参数,所以,这里也得有 2 个输入参数
  3.         a , b = 3 , 5                   # 用于修改计算公式
  4.         print('开始调用被装饰函数')
  5.         k = fx(a * x , b + y)           # 用修改过的参数调用被装饰函数 work()
  6.         print('被装饰函数调用完毕')
  7.         return k + 30                   # 修改对被装饰函数 work() 调用的结果
  8.     return fooB                         # 以内嵌函数 fooB 作为被装饰函数的实际调用句柄

  9. @fooA                                   # 用函数 fooA() 提供的新调用句柄 fooB 替代 work
  10. def work(c , d) :                       # 被装饰函数 work() 带有 2 个输入参数
  11.     print('在被装饰函数内')
  12.     return a * b                        # 被装饰函数有返回值

  13. print('计算结果为 : %d' % work(7 , 9))  # 调用经过装饰的函数 work()
复制代码

    fooA() 装饰 work(),当调用 work() 时,会实际调用由 fooA 提供的内嵌函数 fooB(),并由 fooB() 来负责完成对被装饰函数 work() 的调用
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-4-12 01:43:44 | 显示全部楼层
其实我最能理解的是AI给出的答案 但是大家回复也很辛苦 最佳回答就不给AI的回复了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-1 08:46

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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