鱼C论坛

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

[已解决]闭包与装饰器函数类型为Nonetype

[复制链接]
发表于 2023-7-28 16:50:34 | 显示全部楼层    本楼为最佳答案   
在这个代码中,出现 myfunc 类型为 NoneType 的问题是因为装饰器函数 time_master 没有正确返回内部函数 call_func 的引用。

让我们来分析代码的执行过程:

1. 定义了 time_master 装饰器函数,它接受一个 msg 参数,并返回一个内部函数 call_func 。
2. 在定义 myfunc 函数之前,使用 @time_master('你好') 语法将 myfunc 函数装饰了起来。这相当于执行了 myfunc = time_master('你好')(myfunc) ,即用 time_master('你好') 返回的函数对象来重新绑定 myfunc 变量。
3.  call_func 内部函数在被调用时会执行传入的函数 func() ,在这里就是 myfunc() 。
4.  myfunc 函数内部执行了 time.sleep(2) 来模拟耗时操作,然后打印一条消息。

然而, call_func 内部没有返回任何值,而是直接使用了 func() 执行了 myfunc() 函数。因为 myfunc 函数本身没有返回值,所以 call_func 内部的 return 语句实际上返回了默认值 None ,导致 myfunc 函数被装饰后,其类型变为 NoneType 。

为了解决这个问题,你需要在 call_func 内部添加一个返回语句,将 func() 的返回值传递给外部调用。修改代码如下:

  1. import time

  2. def time_master(msg):
  3.     def call_func(func):
  4.         print("开始运行程序...")
  5.         start = time.time()
  6.         result = func()  # 调用func,并获取其返回值
  7.         stop = time.time()
  8.         print("结束程序运行...")
  9.         print(f"[{msg}]一共耗费了{(stop - start):.2f}秒。")
  10.         return result  # 返回func的返回值
  11.     return call_func


  12. @time_master('你好')
  13. def myfunc():
  14.     time.sleep(2)
  15.     print("I Love FichC ^o^")

  16. print(myfunc.__name__)
复制代码


现在, myfunc 应该会被正确地装饰,并且其类型不再是 NoneType ,而是一个函数类型。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-7-29 14:29:36 | 显示全部楼层
松V溪 发表于 2023-7-29 14:27
厉害,return restult中restult是什么啊?python内置的吗?我昨天想的是直接return func.

result 就是 func 调用的返回值呀,我把 func() 赋值给 result 了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-10-4 04:06

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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