smartsy 发表于 2024-4-11 03:06:24

闭包和装饰器

能否举个其他的例子说明闭包和装饰器呢?小甲鱼课程46节和47节看了很多遍,还是没懂

FishC 发表于 2024-4-11 03:06:35

当然可以!我来给你举个例子。

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

def outer_func(msg):
    def inner_func():
      print(msg)
    return inner_func

my_func = outer_func("Hello")
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"。

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

def decorator_func(original_func):
    def wrapper_func():
      print("装饰器开始")
      original_func()
      print("装饰器结束")
    return wrapper_func

@decorator_func
def my_func():
    print("我是原始函数")

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 小助理,如未能正确解答您的问题,请继续追问。

小甲鱼的二师兄 发表于 2024-4-11 03:26:56

def make_multiplier_of(n):
    def multiplier(x):
      return x * n
    return multiplier

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

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

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

# 使用闭包函数
print(times5(10))# 输出 50
这个你可以理解吗?

小甲鱼的二师兄 发表于 2024-4-11 03:28:19

如果能理解上面闭包的调用,装饰器的执行原理就好理解很多:

def my_decorator(func):
    def wrapper():
      print("Something is happening before the function is called.")
      func()
      print("Something is happening after the function is called.")
    return wrapper

@my_decorator
def say_hello():
    print("Hello!")

# 调用装饰后的函数
say_hello()

小甲鱼的二师兄 发表于 2024-4-11 03:29:14

哈哈,上面 AI 的回复好像已经相当详细了{:10_282:}

jackz007 发表于 2024-4-11 10:42:47

本帖最后由 jackz007 于 2024-4-11 12:13 编辑

【闭包】:
def fooA(a , b) :
    def fooB(x , y) :
      return (x + a) // (y - b)
    return fooB

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

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

print('计算结果为 : %d' % work(7 , 9))# 调用经过装饰的函数 work()
    fooA() 装饰 work(),当调用 work() 时,会实际调用由 fooA 提供的内嵌函数 fooB(),并由 fooB() 来负责完成对被装饰函数 work() 的调用

smartsy 发表于 2024-4-12 01:43:44

其实我最能理解的是AI给出的答案 但是大家回复也很辛苦 最佳回答就不给AI的回复了{:10_254:}
页: [1]
查看完整版本: 闭包和装饰器